diff --git a/Gemfile b/Gemfile
index d09fcca..9e8c2c8 100644
--- a/Gemfile
+++ b/Gemfile
@@ -24,6 +24,9 @@ gem 'simple_form'
# Phone validation
gem 'phony_rails'
+# Picture uploads
+gem 'carrierwave'
+
group :development do
gem 'spring'
gem 'spring-commands-rspec'
diff --git a/Gemfile.lock b/Gemfile.lock
index 2c5503c..06dfa18 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -36,6 +36,11 @@ GEM
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
+ carrierwave (0.10.0)
+ activemodel (>= 3.2.0)
+ activesupport (>= 3.2.0)
+ json (>= 1.7)
+ mime-types (>= 1.16)
celluloid (0.15.2)
timers (~> 1.1.0)
choice (0.1.6)
@@ -221,6 +226,7 @@ PLATFORMS
DEPENDENCIES
capybara
+ carrierwave
coffee-rails
devise
devise-i18n
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index a443db3..ab1028f 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -13,3 +13,12 @@
*= require_tree .
*= require_self
*/
+
+#main {
+ font-size: 16px;
+}
+
+h1 {
+ margin: 0 0 1em 0;
+ font-size: 2em;
+}
diff --git a/app/assets/stylesheets/flash_messages.css.scss b/app/assets/stylesheets/flash_messages.css.scss
new file mode 100644
index 0000000..b47a0b8
--- /dev/null
+++ b/app/assets/stylesheets/flash_messages.css.scss
@@ -0,0 +1,18 @@
+#flash_messages {
+ border: 1px solid #CCC;
+ background-color: #F1F1F1;
+ padding: 10px;
+ margin: 0px 100px 10px 100px;
+
+ div {
+ text-align: center;
+ }
+
+ .notice {
+ color: green;
+ }
+
+ .alert {
+ color: orange;
+ }
+}
\ No newline at end of file
diff --git a/app/assets/stylesheets/forms.css.scss b/app/assets/stylesheets/forms.css.scss
index 0a51e9d..ebc16a8 100644
--- a/app/assets/stylesheets/forms.css.scss
+++ b/app/assets/stylesheets/forms.css.scss
@@ -1,30 +1,31 @@
-#main {
- font-size: 16px;
-}
-h1 {
- margin: 0 0 1em 0;
- font-size: 2em;
+.alert-error {
+ color: red;
}
+
.input {
position: relative;
margin: 0 0 1em 0;
border-top: 0.1em dotted #999;
padding: 1em 0;
}
+
.input label {
font-size: 1em;
display: block;
width: 12em;
float: left;
}
+
.input input, .input textarea, .input select {
font-size: 1em;
width: 20em;
float: left;
}
+
.input textarea {
height: 8em;
}
+
.input .hint, .input .error {
display: block;
clear: both;
@@ -34,11 +35,13 @@ h1 {
margin: 0 0 0 16em;
padding: 1em 0 0 0;
}
+
.input .error {
font-style: normal;
padding: 1em 0 0 0;
color: #F00;
}
+
.input .error::before {
content: "⇧";
display: inline-block;
@@ -46,6 +49,7 @@ h1 {
margin: 0 0.2em 0 0;
transform: translate(0, 0.1em);
}
+
.btn {
display: block;
margin: 2em 0 0 13em;
@@ -63,9 +67,11 @@ h1 {
transition: background 200ms, border 200ms, transform 200ms;
-webkit-transition: background 200ms, border 200ms, transform 200ms;
}
+
.btn:hover {
background: #152551;
}
+
.btn:active {
background: #597AD2;
border-bottom: 0.2em solid #000;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d83690e..948c310 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,4 +2,13 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
+ before_filter :configure_permitted_parameters, if: :devise_controller?
+
+ protected
+
+ def configure_permitted_parameters
+ devise_parameter_sanitizer.for(:account_update) do |u|
+ u.permit(:email, :password, :password_confirmation, :current_password, speaker_profile_attributes: [:first_name, :last_name, :public_email, :organisation, :github, :twitter, :mobile_phone, :biography, :picture, :id])
+ end
+ end
end
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
new file mode 100644
index 0000000..a781c0c
--- /dev/null
+++ b/app/controllers/registrations_controller.rb
@@ -0,0 +1,35 @@
+class RegistrationsController < Devise::RegistrationsController
+ def edit
+ resource.build_speaker_profile unless resource.speaker_profile.present?
+ end
+
+ def update
+ @user = User.find(current_user.id)
+
+ successfully_updated = if needs_password?(@user, params)
+ @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update))
+ else
+ # remove the virtual current_password attribute
+ # update_without_password doesn't know how to ignore it
+ params[:user].delete(:current_password)
+ @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update))
+ end
+
+ if successfully_updated
+ set_flash_message :notice, :updated
+ # Sign in the user bypassing validation in case their password changed
+ sign_in @user, :bypass => true
+ redirect_to after_update_path_for(@user)
+ else
+ render "edit"
+ end
+ end
+
+ private
+
+ def needs_password?(user, params)
+ user.email != params[:user][:email] ||
+ params[:user][:password].present? ||
+ params[:user][:password_confirmation].present?
+ end
+end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
new file mode 100644
index 0000000..c9f6a1a
--- /dev/null
+++ b/app/controllers/sessions_controller.rb
@@ -0,0 +1,9 @@
+class SessionsController < Devise::SessionsController
+ def after_sign_in_path_for(user)
+ if user.speaker_profile.present?
+ stored_location_for(user) || signed_in_root_path(user)
+ else
+ edit_user_registration_path
+ end
+ end
+end
diff --git a/app/controllers/speaker_profiles_controller.rb b/app/controllers/speaker_profiles_controller.rb
new file mode 100644
index 0000000..a51e033
--- /dev/null
+++ b/app/controllers/speaker_profiles_controller.rb
@@ -0,0 +1,16 @@
+class SpeakerProfilesController < ApplicationController
+ before_filter :authenticate_user!
+ before_action :assign_speaker_profile
+
+ def edit
+ end
+
+ def update
+ end
+
+ private
+
+ def assign_speaker_profile
+ @speaker_profile = SpeakerProfile.find_or_initialize_by(user: current_user)
+ end
+end
diff --git a/app/models/speaker_profile.rb b/app/models/speaker_profile.rb
index 4af25d1..9e0ce34 100644
--- a/app/models/speaker_profile.rb
+++ b/app/models/speaker_profile.rb
@@ -3,7 +3,7 @@ class SpeakerProfile < ActiveRecord::Base
validates :first_name, presence: true
validates :last_name, presence: true
- validates :photo_url, presence: true
+ validates :picture, presence: true
validates :mobile_phone, phony_plausible: true, presence: true
validates :biography, presence: true
validates :public_email, format: {with: /\A[^@]+@[^@]+\z/}, allow_blank: true
@@ -12,6 +12,8 @@ class SpeakerProfile < ActiveRecord::Base
phony_normalize :mobile_phone, default_country_code: 'BG'
+ mount_uploader :picture, PictureUploader
+
def twitter=(handle)
write_attribute :twitter, handle.gsub(/\A@/,'') if handle
end
diff --git a/app/models/user.rb b/app/models/user.rb
index f7fa261..8ae638a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -7,4 +7,6 @@ class User < ActiveRecord::Base
has_one :speaker_profile
has_many :lectures
has_many :workshops
+
+ accepts_nested_attributes_for :speaker_profile, update_only: true
end
diff --git a/app/uploaders/picture_uploader.rb b/app/uploaders/picture_uploader.rb
new file mode 100644
index 0000000..217f662
--- /dev/null
+++ b/app/uploaders/picture_uploader.rb
@@ -0,0 +1,51 @@
+# encoding: utf-8
+
+class PictureUploader < CarrierWave::Uploader::Base
+
+ # Include RMagick or MiniMagick support:
+ # include CarrierWave::RMagick
+ # include CarrierWave::MiniMagick
+
+ # Choose what kind of storage to use for this uploader:
+ storage :file
+ # storage :fog
+
+ # Override the directory where uploaded files will be stored.
+ # This is a sensible default for uploaders that are meant to be mounted:
+ def store_dir
+ "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
+ end
+
+ # Provide a default URL as a default if there hasn't been a file uploaded:
+ # def default_url
+ # # For Rails 3.1+ asset pipeline compatibility:
+ # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
+ #
+ # "/images/fallback/" + [version_name, "default.png"].compact.join('_')
+ # end
+
+ # Process files as they are uploaded:
+ # process :scale => [200, 300]
+ #
+ # def scale(width, height)
+ # # do something
+ # end
+
+ # Create different versions of your uploaded files:
+ # version :thumb do
+ # process :resize_to_fit => [50, 50]
+ # end
+
+ # Add a white list of extensions which are allowed to be uploaded.
+ # For images you might use something like this:
+ # def extension_white_list
+ # %w(jpg jpeg gif png)
+ # end
+
+ # Override the filename of the uploaded files:
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
+ # def filename
+ # "something.jpg" if original_filename
+ # end
+
+end
diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb
deleted file mode 100644
index 949b172..0000000
--- a/app/views/devise/confirmations/new.html.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-
Resend confirmation instructions
-
-<%= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
- <%= f.error_notification %>
- <%= f.full_error :confirmation_token %>
-
-
- <%= f.input :email, required: true, autofocus: true %>
-
-
-
- <%= f.button :submit, "Resend confirmation instructions" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/confirmations/new.html.slim b/app/views/devise/confirmations/new.html.slim
new file mode 100644
index 0000000..4437d9d
--- /dev/null
+++ b/app/views/devise/confirmations/new.html.slim
@@ -0,0 +1,13 @@
+h2.entry-title Повторно изпращане на инструкции за потвърждаване на акаунт
+
+= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
+ = f.error_notification
+ = f.full_error :confirmation_token
+
+ .form-inputs
+ = f.input :email, required: true, autofocus: true, hint: false
+
+ .form-actions
+ = f.button :submit, 'Изпрати отново инструкциите'
+
+== render 'devise/shared/links'
diff --git a/app/views/devise/mailer/confirmation_instructions.html.erb b/app/views/devise/mailer/confirmation_instructions.html.erb
index dc55f64..879307d 100644
--- a/app/views/devise/mailer/confirmation_instructions.html.erb
+++ b/app/views/devise/mailer/confirmation_instructions.html.erb
@@ -1,5 +1,5 @@
-Welcome <%= @email %>!
+Добре дошли, <%= @email %>!
-You can confirm your account email through the link below:
+Можете да потвърдите акаунта си като кликнете на линка отдолу:
-<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>
+<%= link_to 'Потвърди акаунта ми', confirmation_url(@resource, confirmation_token: @token) %>
diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb
index f667dc1..387dcaa 100644
--- a/app/views/devise/mailer/reset_password_instructions.html.erb
+++ b/app/views/devise/mailer/reset_password_instructions.html.erb
@@ -1,8 +1,8 @@
-Hello <%= @resource.email %>!
+Здравейте, <%= @resource.email %>!
-Someone has requested a link to change your password. You can do this through the link below.
+Някой поиска линк за промяна на парола на аканута Ви. Паролата може да бъде променена от линкът отдолу.
-<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>
+<%= link_to 'Промяна на парола', edit_password_url(@resource, reset_password_token: @token) %>
-If you didn't request this, please ignore this email.
-Your password won't change until you access the link above and create a new one.
+Ако не желаете да смените паролата си, моля изтрийте това писмо.
+Паролата Ви няма да бъде променена докато не кликнете горния линк и не въведете нова парола.
diff --git a/app/views/devise/mailer/unlock_instructions.html.erb b/app/views/devise/mailer/unlock_instructions.html.erb
index 41e148b..145011d 100644
--- a/app/views/devise/mailer/unlock_instructions.html.erb
+++ b/app/views/devise/mailer/unlock_instructions.html.erb
@@ -1,7 +1,7 @@
-Hello <%= @resource.email %>!
+Здравейте, <%= @resource.email %>!
-Your account has been locked due to an excessive number of unsuccessful sign in attempts.
+Акаунтът Ви беше заключен поради голям брой неуспешни опити за влизане в него.
-Click the link below to unlock your account:
+Кликнете линкът отдолу, за да го отключите:
-<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>
+<%= link_to 'Отключване на акаунт', unlock_url(@resource, unlock_token: @token) %>
diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb
deleted file mode 100644
index 8f995ed..0000000
--- a/app/views/devise/passwords/edit.html.erb
+++ /dev/null
@@ -1,19 +0,0 @@
-Change your password
-
-<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
- <%= f.error_notification %>
-
- <%= f.input :reset_password_token, as: :hidden %>
- <%= f.full_error :reset_password_token %>
-
-
- <%= f.input :password, label: "New password", required: true, autofocus: true %>
- <%= f.input :password_confirmation, label: "Confirm your new password", required: true %>
-
-
-
- <%= f.button :submit, "Change my password" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/passwords/edit.html.slim b/app/views/devise/passwords/edit.html.slim
new file mode 100644
index 0000000..2a698ca
--- /dev/null
+++ b/app/views/devise/passwords/edit.html.slim
@@ -0,0 +1,16 @@
+h2.entry-title Промяна на парола
+
+= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f|
+ = f.error_notification
+
+ = f.input :reset_password_token, as: :hidden
+ = f.full_error :reset_password_token
+
+ .form-inputs
+ = f.input :password, required: true, autofocus: true
+ = f.input :password_confirmation, required: true
+
+ .form-actions
+ = f.button :submit, 'Промяна на паролата'
+
+= render 'devise/shared/links'
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb
deleted file mode 100644
index d1503e7..0000000
--- a/app/views/devise/passwords/new.html.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-Forgot your password?
-
-<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
- <%= f.error_notification %>
-
-
- <%= f.input :email, required: true, autofocus: true %>
-
-
-
- <%= f.button :submit, "Send me reset password instructions" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/passwords/new.html.slim b/app/views/devise/passwords/new.html.slim
new file mode 100644
index 0000000..81f8378
--- /dev/null
+++ b/app/views/devise/passwords/new.html.slim
@@ -0,0 +1,12 @@
+h2.entry-title Забравена парола?
+
+= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
+ = f.error_notification
+
+ .form-inputs
+ = f.input :email, required: true, autofocus: true, hint: false
+
+ .form-actions
+ = f.button :submit, 'Изпрати ми инструкции за промяна на парола'
+
+== render 'devise/shared/links'
diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb
deleted file mode 100644
index 5db350b..0000000
--- a/app/views/devise/registrations/edit.html.erb
+++ /dev/null
@@ -1,27 +0,0 @@
-Edit <%= resource_name.to_s.humanize %>
-
-<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
- <%= f.error_notification %>
-
-
-
-
- <%= f.button :submit, "Update" %>
-
-<% end %>
-
-Cancel my account
-
-Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %>
-
-<%= link_to "Back", :back %>
diff --git a/app/views/devise/registrations/edit.html.slim b/app/views/devise/registrations/edit.html.slim
new file mode 100644
index 0000000..53d5b36
--- /dev/null
+++ b/app/views/devise/registrations/edit.html.slim
@@ -0,0 +1,29 @@
+= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
+ .form_inputs
+ h2.entry-title Лекторски профил
+ = f.error_notification
+ = f.simple_fields_for :speaker_profile do |ff|
+ = ff.input :picture, as: :file
+ = ff.input :first_name
+ = ff.input :last_name
+ = ff.input :public_email
+ = ff.input :organisation
+ = ff.input :github
+ = ff.input :twitter
+ = ff.input :mobile_phone, input_html: {value: resource.speaker_profile.mobile_phone.try(:phony_formatted, format: :international)}
+ = ff.input :biography
+
+ .form-inputs
+ h3.entry-title Данни за вход в системата
+ = f.input :email, required: true, autofocus: true
+
+ - if devise_mapping.confirmable? && resource.pending_reconfirmation?
+ p
+ Очаква се потвърждение на: #{resource.unconfirmed_email}
+
+ = f.input :password, autocomplete: "off", hint: "Не попълвайте, ако не желаете да промените паролата си", required: false
+ = f.input :password_confirmation, required: false
+ = f.input :current_password, hint: "Попълнете, ако искате да промените паролата или имейл адреса си.", required: true
+
+ .form-actions
+ = f.button :submit, 'Обнови'
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb
deleted file mode 100644
index 090fb29..0000000
--- a/app/views/devise/registrations/new.html.erb
+++ /dev/null
@@ -1,17 +0,0 @@
-Sign up
-
-<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
- <%= f.error_notification %>
-
-
- <%= f.input :email, required: true, autofocus: true %>
- <%= f.input :password, required: true %>
- <%= f.input :password_confirmation, required: true %>
-
-
-
- <%= f.button :submit, "Sign up" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/registrations/new.html.slim b/app/views/devise/registrations/new.html.slim
new file mode 100644
index 0000000..f024368
--- /dev/null
+++ b/app/views/devise/registrations/new.html.slim
@@ -0,0 +1,14 @@
+h2.entry-title Регистрация
+
+= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
+ = f.error_notification
+
+ .form-inputs
+ = f.input :email, required: true, autofocus: true
+ = f.input :password, required: true
+ = f.input :password_confirmation, required: true
+
+ .form-actions
+ = f.button :submit
+
+== render 'devise/shared/links'
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
deleted file mode 100644
index c790b49..0000000
--- a/app/views/devise/sessions/new.html.erb
+++ /dev/null
@@ -1,15 +0,0 @@
-Sign in
-
-<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
-
- <%= f.input :email, required: false, autofocus: true %>
- <%= f.input :password, required: false %>
- <%= f.input :remember_me, as: :boolean if devise_mapping.rememberable? %>
-
-
-
- <%= f.button :submit, "Sign in" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim
new file mode 100644
index 0000000..996b085
--- /dev/null
+++ b/app/views/devise/sessions/new.html.slim
@@ -0,0 +1,12 @@
+h2.entry-title Вход
+
+= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
+ .form-inputs
+ = f.input :email, required: false, autofocus: true, hint: false
+ = f.input :password, required: false, hint: false
+ = f.input :remember_me, as: :boolean if devise_mapping.rememberable?
+
+ .form-actions
+ = f.button :submit, 'Влез'
+
+== render 'devise/shared/links'
diff --git a/app/views/devise/shared/_links.erb b/app/views/devise/shared/_links.erb
deleted file mode 100644
index d84bdde..0000000
--- a/app/views/devise/shared/_links.erb
+++ /dev/null
@@ -1,25 +0,0 @@
-<%- if controller_name != 'sessions' %>
- <%= link_to "Sign in", new_session_path(resource_name) %>
-<% end -%>
-
-<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
- <%= link_to "Sign up", new_registration_path(resource_name) %>
-<% end -%>
-
-<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
- <%= link_to "Forgot your password?", new_password_path(resource_name) %>
-<% end -%>
-
-<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
- <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %>
-<% end -%>
-
-<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
- <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %>
-<% end -%>
-
-<%- if devise_mapping.omniauthable? %>
- <%- resource_class.omniauth_providers.each do |provider| %>
- <%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %>
- <% end -%>
-<% end -%>
diff --git a/app/views/devise/shared/_links.html.slim b/app/views/devise/shared/_links.html.slim
new file mode 100644
index 0000000..366b7c3
--- /dev/null
+++ b/app/views/devise/shared/_links.html.slim
@@ -0,0 +1,23 @@
+- if controller_name != 'sessions'
+ = link_to 'Вход', new_session_path(resource_name)
+ br
+
+- if devise_mapping.registerable? && controller_name != 'registrations'
+ = link_to 'Регистрация', new_registration_path(resource_name)
+ br
+
+- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
+ = link_to 'Забравена парола?', new_password_path(resource_name)
+ br
+
+- if devise_mapping.confirmable? && controller_name != 'confirmations'
+ = link_to 'Не Сте получили инструкции за потвърждение?', new_confirmation_path(resource_name)
+ br
+
+- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
+ = link_to 'Не Сте получили инструкции за отключване?', new_unlock_path(resource_name)
+ br
+
+- if devise_mapping.omniauthable?
+ - resource_class.omniauth_providers.each do |provider|
+ = link_to 'Влез с #{provider.to_s.titleize}', omniauth_authorize_path(resource_name, provider)
diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb
deleted file mode 100644
index 788f62e..0000000
--- a/app/views/devise/unlocks/new.html.erb
+++ /dev/null
@@ -1,16 +0,0 @@
-Resend unlock instructions
-
-<%= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
- <%= f.error_notification %>
- <%= f.full_error :unlock_token %>
-
-
- <%= f.input :email, required: true, autofocus: true %>
-
-
-
- <%= f.button :submit, "Resend unlock instructions" %>
-
-<% end %>
-
-<%= render "devise/shared/links" %>
diff --git a/app/views/devise/unlocks/new.html.slim b/app/views/devise/unlocks/new.html.slim
new file mode 100644
index 0000000..9b5abf7
--- /dev/null
+++ b/app/views/devise/unlocks/new.html.slim
@@ -0,0 +1,13 @@
+h2 Изпрати отново инструкции за отключване
+
+= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f|
+ = f.error_notification
+ = f.full_error :unlock_token
+
+ .form-inputs
+ = f.input :email, required: true, autofocus: true, hint: false
+
+ .form-actions
+ = f.button :submit, 'Изпрати отново инструкциите'
+
+== render 'devise/shared/links'
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index cb9643b..55074fb 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -26,6 +26,7 @@
+ <%= render('/shared/flash_messages') unless flash.empty? %>
<%= yield %>
diff --git a/app/views/shared/_flash_messages b/app/views/shared/_flash_messages
new file mode 100644
index 0000000..c94abd1
--- /dev/null
+++ b/app/views/shared/_flash_messages
@@ -0,0 +1,3 @@
+div#flash_messages
+ - flash.each do |key, value|
+ = content_tag :div, value, class: "flash #{key}"
diff --git a/app/views/shared/_flash_messages.html.slim b/app/views/shared/_flash_messages.html.slim
new file mode 100644
index 0000000..c94abd1
--- /dev/null
+++ b/app/views/shared/_flash_messages.html.slim
@@ -0,0 +1,3 @@
+div#flash_messages
+ - flash.each do |key, value|
+ = content_tag :div, value, class: "flash #{key}"
diff --git a/app/views/speaker_profiles/_form.html.slim b/app/views/speaker_profiles/_form.html.slim
new file mode 100644
index 0000000..6c3702b
--- /dev/null
+++ b/app/views/speaker_profiles/_form.html.slim
@@ -0,0 +1,14 @@
+== simple_form_for @speaker_profile do |form|
+ p
+ = form.error_notification
+
+ .form-inputs
+ = form.input :first_name, autofocus: true
+ = form.input :last_name
+ = form.input :public_email
+ = form.input :organisation
+ = form.input :github
+ = form.input :twitter
+ = form.input :mobile_phone
+ = form.input :biography
+ = form.button :submit
diff --git a/app/views/speaker_profiles/edit.html.slim b/app/views/speaker_profiles/edit.html.slim
new file mode 100644
index 0000000..bcfe4cf
--- /dev/null
+++ b/app/views/speaker_profiles/edit.html.slim
@@ -0,0 +1,3 @@
+h1.entry-title Редакция на лекторски профил
+
+== render 'form'
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index f26b51b..91c3d13 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -22,6 +22,9 @@
bg:
activerecord:
models:
+ user:
+ one: Потребител
+ other: Потребители
lecture:
one: Лекция
other: Лекции
@@ -30,6 +33,22 @@ bg:
other: Уъркшопи
track: Поток от лекции
attributes:
+ user:
+ email: E-mail
+ current_password: Текуща парола
+ password: Парола
+ password_confirmation: Отново паролата
+ remember_me: Запомни ме
+ speaker_profile:
+ picture: Снимка
+ first_name: Име
+ last_name: Фамилия
+ organisation: Организация
+ public_email: Публичен email
+ mobile_phone: Мобилен телефон
+ biography: Биография
+ github: Github акаунт
+ twitter: Twitter акаунт
lecture:
title: Заглавие
subtitle: Подзаглавие
@@ -48,6 +67,14 @@ bg:
description: Описание
notes: Забележки
track: Поток от лекции
+ errors:
+ models:
+ user:
+ attributes:
+ email:
+ invalid: не е валиден имейл адрес
+ password_confirmation:
+ confirmation: не съответства на паролата
errors:
messages:
improbable_phone: 'не е валиден телефонен номер'
\ No newline at end of file
diff --git a/config/locales/simple_form.bg.yml b/config/locales/simple_form.bg.yml
index 4641608..c9a6497 100644
--- a/config/locales/simple_form.bg.yml
+++ b/config/locales/simple_form.bg.yml
@@ -1,13 +1,27 @@
bg:
simple_form:
- "yes": 'Да'
- "no": 'Не'
+ "yes": Да
+ "no": Не
required:
- text: 'Задължително поле'
+ text: Задължително поле
mark: '*'
error_notification:
- default_message: "Моля разгледайте проблемите по-долу:"
+ default_message: 'Моля разгледайте посочените грешки във формуляра:'
hints:
+ user:
+ email: Имейл адресът Ви. Ще бъде видим само от организаторите.
+ password: Парола с дължина между 8 и 128 символа
+ password_confirmation: Отново въведената отгоре парола
+ speaker_profile:
+ picture: Ваша снимка
+ first_name: Малкото Ви име
+ last_name: Фамилното Ви име
+ organisation: Организацията, която представлявате
+ public_email: E-mail адрес, който ще бъде видим за посетителите
+ mobile_phone: Мобилен телефон, който ще бъде видим само за организаторите
+ biography: Опишете се с няколко изречения в трето лице :).
+ github: Github акаунтът Ви
+ twitter: Twitter акаунтът Ви
lecture:
title: Заглавието на лекцията Ви
subtitle: Подзаглавието на лекцията Ви (ако има такова)
@@ -25,4 +39,7 @@ bg:
language: Език, на който ще бъде воден уъркшопа
abstract: Резюме на уъркшопа, което да може да бъде прочетено от посетителите
description: Подробно описание на уъркшопа, което да бъде използвано от организаторския екип
- notes: Забележки, които искате да споделите с организаторския екип
\ No newline at end of file
+ notes: Забележки, които искате да споделите с организаторския екип
+ labels:
+ user:
+ a: b
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 65c7913..13994b4 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -2,7 +2,11 @@ Rails.application.routes.draw do
resources :lectures, only: [:index, :new, :create, :edit, :update, :show]
resources :workshops, only: [:index, :new, :create, :edit, :update, :show]
- devise_for :users
+ devise_for :users, controllers: {registrations: 'registrations', sessions: 'sessions'}
+
+ resource :user, only: [] do
+ resource :speaker_profile, only: [:edit, :update]
+ end
root 'home#index'
# The priority is based upon order of creation: first created -> highest priority.
diff --git a/db/migrate/20140807103632_create_speaker_profiles.rb b/db/migrate/20140807103632_create_speaker_profiles.rb
index 286e036..9abfa88 100644
--- a/db/migrate/20140807103632_create_speaker_profiles.rb
+++ b/db/migrate/20140807103632_create_speaker_profiles.rb
@@ -1,15 +1,15 @@
class CreateSpeakerProfiles < ActiveRecord::Migration
def change
create_table :speaker_profiles do |t|
- t.string :first_name, null: false
- t.string :last_name, null: false
+ t.string :first_name
+ t.string :last_name
t.string :organisation
t.string :public_email
- t.string :photo_url, null: false
- t.string :mobile_phone, null: false
- t.text :biography, null: false
- t.string :github, null: false
- t.string :twitter, null: false
+ t.string :photo_url
+ t.string :mobile_phone
+ t.text :biography
+ t.string :github
+ t.string :twitter
t.timestamps
end
diff --git a/db/migrate/20140831121527_rename_picture_url_to_picture_in_speaker_profiles.rb b/db/migrate/20140831121527_rename_picture_url_to_picture_in_speaker_profiles.rb
new file mode 100644
index 0000000..fc253c3
--- /dev/null
+++ b/db/migrate/20140831121527_rename_picture_url_to_picture_in_speaker_profiles.rb
@@ -0,0 +1,5 @@
+class RenamePictureUrlToPictureInSpeakerProfiles < ActiveRecord::Migration
+ def change
+ rename_column :speaker_profiles, :photo_url, :picture
+ end
+end
diff --git a/public/uploads/.keep b/public/uploads/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/public/uploads/tmp/.keep b/public/uploads/tmp/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/spec/factories/speaker_profiles.rb b/spec/factories/speaker_profiles.rb
index 2e64802..dbabf5a 100644
--- a/spec/factories/speaker_profiles.rb
+++ b/spec/factories/speaker_profiles.rb
@@ -6,7 +6,7 @@ FactoryGirl.define do
last_name "Doe"
organisation "Example Org"
public_email "a@b.com"
- photo_url "http://placehold.it/50x50"
+ picture { Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec', 'support', 'picture.jpg')) }
mobile_phone "0883444555"
biography "Lorem ipsum"
github "octocat"
diff --git a/spec/models/speaker_profile_spec.rb b/spec/models/speaker_profile_spec.rb
index 008941d..76453df 100644
--- a/spec/models/speaker_profile_spec.rb
+++ b/spec/models/speaker_profile_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe SpeakerProfile, :type => :model do
expect(build(:speaker_profile, last_name: nil)).to have_error_on :last_name
end
- it 'is invalid without a photo' do
- expect(build(:speaker_profile, photo_url: nil)).to have_error_on :photo_url
+ it 'is invalid without a picture' do
+ expect(build(:speaker_profile, picture: nil)).to have_error_on :picture
end
describe 'mobile_phone' do
diff --git a/spec/support/picture.jpg b/spec/support/picture.jpg
new file mode 100644
index 0000000..e69de29