recruiter 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/Rakefile +2 -0
- data/app/assets/images/ruby.png +0 -0
- data/app/assets/images/ruby_72x72.png +0 -0
- data/app/assets/images/ruby_rotated.png +0 -0
- data/app/assets/images/ruby_worker.png +0 -0
- data/app/assets/javascripts/recruiter/application.js +3 -0
- data/app/assets/javascripts/recruiter/filters.js +35 -0
- data/app/assets/javascripts/recruiter/site.js +3 -0
- data/app/assets/stylesheets/recruiter/application.css.scss +7 -0
- data/app/assets/stylesheets/recruiter/foundation_and_overrides.scss +1251 -0
- data/app/assets/stylesheets/recruiter/gh-fork-ribbon.css +140 -0
- data/app/assets/stylesheets/recruiter/site.css.sass +116 -0
- data/app/assets/stylesheets/recruiter/variables.css.sass +6 -0
- data/app/controllers/recruiter/filters_controller.rb +14 -0
- data/app/controllers/recruiter/jobs_controller.rb +18 -0
- data/app/controllers/recruiter/omniauth_callbacks_controller.rb +45 -0
- data/app/controllers/recruiter/users/jobs_controller.rb +59 -0
- data/app/controllers/recruiter/users/user_controller.rb +8 -0
- data/app/controllers/recruiter_controller.rb +13 -0
- data/app/decorators/recruiter/job_decorator.rb +49 -0
- data/app/decorators/recruiter/user_decorator.rb +22 -0
- data/app/helpers/recruiter/crud_flash_messager_helper.rb +21 -0
- data/app/helpers/recruiter/form_helper.rb +29 -0
- data/app/helpers/recruiter/header_helper.rb +13 -0
- data/app/helpers/recruiter/icons_helper.rb +29 -0
- data/app/helpers/recruiter/links_helper.rb +59 -0
- data/app/helpers/recruiter/markdown_helper.rb +12 -0
- data/app/helpers/recruiter/oauth_providers_helper.rb +23 -0
- data/app/helpers/recruiter/show_helper.rb +29 -0
- data/app/models/recruiter/city.rb +9 -0
- data/app/models/recruiter/custom_devise_failure.rb +7 -0
- data/app/models/recruiter/filters.rb +44 -0
- data/app/models/recruiter/filters/city_filter.rb +21 -0
- data/app/models/recruiter/filters/job_filter.rb +21 -0
- data/app/models/recruiter/filters/state_filter.rb +17 -0
- data/app/models/recruiter/job.rb +34 -0
- data/app/{helpers/recruiter/application_helper.rb → models/recruiter/oauth.rb} +1 -1
- data/app/models/recruiter/oauth/base.rb +24 -0
- data/app/models/recruiter/oauth/facebook.rb +6 -0
- data/app/models/recruiter/oauth/github.rb +6 -0
- data/app/models/recruiter/oauth/google.rb +9 -0
- data/app/models/recruiter/state.rb +9 -0
- data/app/models/recruiter/tag.rb +6 -0
- data/app/models/recruiter/user.rb +11 -0
- data/app/views/devise/sessions/new.html.erb +8 -0
- data/app/views/kaminari/_first_page.html.erb +11 -0
- data/app/views/kaminari/_gap.html.erb +8 -0
- data/app/views/kaminari/_last_page.html.erb +11 -0
- data/app/views/kaminari/_next_page.html.erb +11 -0
- data/app/views/kaminari/_page.html.erb +12 -0
- data/app/views/kaminari/_paginator.html.erb +23 -0
- data/app/views/kaminari/_prev_page.html.erb +11 -0
- data/app/views/layouts/recruiter/application.html.erb +28 -10
- data/app/views/recruiter/_analytics.html.erb +10 -0
- data/app/views/recruiter/_filters.html.erb +17 -0
- data/app/views/recruiter/_flashes.html.erb +14 -0
- data/app/views/recruiter/_footer.html.erb +7 -0
- data/app/views/recruiter/_form_actions.html.erb +4 -0
- data/app/views/recruiter/_javascript.html.erb +10 -0
- data/app/views/recruiter/_login_button.html.erb +15 -0
- data/app/views/recruiter/_login_links.html.erb +7 -0
- data/app/views/recruiter/_login_status.html.erb +8 -0
- data/app/views/recruiter/_show_actions.html.erb +6 -0
- data/app/views/recruiter/_show_item.html.erb +8 -0
- data/app/views/recruiter/_tags.html.erb +6 -0
- data/app/views/recruiter/_top_menu.html.erb +28 -0
- data/app/views/recruiter/jobs/_job.html.erb +14 -0
- data/app/views/recruiter/jobs/index.html.erb +14 -0
- data/app/views/recruiter/jobs/show.html.erb +1 -0
- data/app/views/recruiter/users/jobs/_form.html.erb +30 -0
- data/app/views/recruiter/users/jobs/_job.html.erb +35 -0
- data/app/views/recruiter/users/jobs/edit.html.erb +3 -0
- data/app/views/recruiter/users/jobs/index.html.erb +24 -0
- data/app/views/recruiter/users/jobs/new.html.erb +3 -0
- data/app/views/recruiter/users/jobs/show.html.erb +4 -0
- data/config/initializers/devise.rb +272 -0
- data/config/initializers/simple_form.rb +145 -0
- data/config/routes.rb +19 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20140617180316_create_recruiter_states.rb +12 -0
- data/db/migrate/20140617180934_create_recruiter_cities.rb +14 -0
- data/db/migrate/20140618164609_create_recruiter_users.rb +51 -0
- data/db/migrate/20140618165301_add_name_to_users.rb +5 -0
- data/db/migrate/20140618165802_create_recruiter_jobs.rb +14 -0
- data/db/migrate/20140618170815_create_recruiter_tags.rb +13 -0
- data/db/migrate/20140618170904_create_recruiter_jobs_tags.rb +10 -0
- data/lib/generators/templates/locales/devise.en.yml +59 -0
- data/lib/generators/templates/locales/devise.pt-BR.yml +60 -0
- data/lib/generators/templates/locales/en.yml +11 -0
- data/lib/generators/templates/locales/pt-BR.yml +237 -0
- data/lib/generators/templates/locales/recruiter.pt-BR.yml +78 -0
- data/lib/generators/templates/locales/simple_form.en.yml +26 -0
- data/lib/recruiter.rb +12 -0
- data/lib/recruiter/engine.rb +31 -0
- data/lib/recruiter/version.rb +1 -1
- metadata +362 -11
- data/app/assets/stylesheets/recruiter/application.css +0 -15
- data/app/controllers/recruiter/application_controller.rb +0 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
class UserDecorator < Draper::Decorator
|
|
3
|
+
delegate_all
|
|
4
|
+
|
|
5
|
+
def avatar(width = 50, height = 50)
|
|
6
|
+
url ||= image_url
|
|
7
|
+
url ||= gravatar_url
|
|
8
|
+
h.image_tag(url, width: width, height: height)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def image_url
|
|
12
|
+
@image_url ||= object.provider_data.deep_symbolize_keys[:info][:image]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def gravatar_url
|
|
16
|
+
if email
|
|
17
|
+
hash = Digest::MD5.hexdigest(email)
|
|
18
|
+
"http://www.gravatar.com/avatar/#{hash}"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module CrudFlashMessagerHelper
|
|
3
|
+
def crud_flash(result, &block)
|
|
4
|
+
unless request.xhr?
|
|
5
|
+
result ? set_crud_success_flash : set_crud_error_flash
|
|
6
|
+
yield if result && block_given?
|
|
7
|
+
end
|
|
8
|
+
result
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def set_crud_success_flash
|
|
12
|
+
default = t("recruiter.messages.crud.#{params[:action]}.success")
|
|
13
|
+
flash[:notice] = t('.success', default: default)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def set_crud_error_flash
|
|
17
|
+
default = t("recruiter.messages.crud.#{params[:action]}.error")
|
|
18
|
+
flash.now[:alert] = t('.success', default: default)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module FormHelper
|
|
3
|
+
def options_for_states
|
|
4
|
+
options_for(State)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def options_for_available_states
|
|
8
|
+
options_for(State.with_open_jobs)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def options_for_available_cities(state_id)
|
|
12
|
+
options_for City.with_open_jobs.where(state_id: state_id)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def options_for_cities(state_id = nil)
|
|
16
|
+
options_for City.where(state_id: state_id)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def options_for(scope)
|
|
20
|
+
scope.order(:name).select(:name, :id).map do |row|
|
|
21
|
+
[row.name, row.id]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def tags
|
|
26
|
+
Tag.order(:sequence)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# http://zurb.com/playground/foundation-icon-fonts-3
|
|
2
|
+
|
|
3
|
+
module Recruiter
|
|
4
|
+
module IconsHelper
|
|
5
|
+
def icon(name, klass = nil)
|
|
6
|
+
content_tag(:i, nil, class: "fi-#{name} #{klass}")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def new_icon(klass = nil)
|
|
10
|
+
icon(:plus, klass)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def mail_icon(klass = nil)
|
|
14
|
+
icon(:mail, klass)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def edit_icon(klass = nil)
|
|
18
|
+
icon('page-edit', klass)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def destroy_icon(klass = nil)
|
|
22
|
+
icon(:trash, klass)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def show_icon(klass = nil)
|
|
26
|
+
icon(:eye, klass)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module LinksHelper
|
|
3
|
+
def button_link(url, classes = nil, options = {}, &block)
|
|
4
|
+
classes = [options[:class], 'button', classes].compact
|
|
5
|
+
options.merge! class: classes
|
|
6
|
+
link_to url, options, &block
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def new_link(url, options = {})
|
|
10
|
+
options.reverse_merge!({ title: t('recruiter.links.new') })
|
|
11
|
+
|
|
12
|
+
link_to(url, options) do
|
|
13
|
+
[new_icon, t('recruiter.links.new')].join(" ").html_safe
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def edit_link(url, options = {}, &block)
|
|
18
|
+
options.reverse_merge!({ title: t('recruiter.links.edit') })
|
|
19
|
+
button_link(url, 'warning tiny', options) do
|
|
20
|
+
edit_icon
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def destroy_link(url, options = { }, &block)
|
|
25
|
+
options.reverse_merge!({
|
|
26
|
+
method: :delete,
|
|
27
|
+
data: { confirm: t('recruiter.messages.confirm_destroy')},
|
|
28
|
+
title: t('recruiter.links.destroy'),
|
|
29
|
+
})
|
|
30
|
+
button_link(url, 'alert tiny', options) do
|
|
31
|
+
destroy_icon
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def show_link(url, options = {}, &block)
|
|
36
|
+
options.reverse_merge!({ title: t('recruiter.links.show') })
|
|
37
|
+
button_link(url, 'secondary tiny', options) do
|
|
38
|
+
show_icon
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def back_link(url = { action: :index }, options = {}, &block)
|
|
43
|
+
button_link(url, 'warning', options) do
|
|
44
|
+
t('recruiter.links.back')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def cancel_link(url = { action: :index }, options = {}, &block)
|
|
49
|
+
button_link(url, 'alert', options) do
|
|
50
|
+
t('recruiter.links.cancel')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def submit_button
|
|
55
|
+
action = params[:action]
|
|
56
|
+
content_tag(:button, t("recruiter.submit.#{action}"), class: 'success')
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module MarkdownHelper
|
|
3
|
+
def to_markdown(text)
|
|
4
|
+
renderer.render(text).html_safe
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def renderer
|
|
8
|
+
@renderer ||= Redcarpet::Render::HTML.new(filter_html: true)
|
|
9
|
+
@md_renderer ||= Redcarpet::Markdown.new(@renderer)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module OauthProvidersHelper
|
|
3
|
+
def available_oauth_providers
|
|
4
|
+
{
|
|
5
|
+
github: :github,
|
|
6
|
+
google: :google_oauth2,
|
|
7
|
+
facebook: :facebook,
|
|
8
|
+
}.select do |key, provider|
|
|
9
|
+
ENV["#{key.to_s.upcase}_KEY"]
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def provider_icon(provider)
|
|
14
|
+
icon(provider_icon_class(provider))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def provider_icon_class(provider)
|
|
18
|
+
{
|
|
19
|
+
google_oauth2: 'social-google-plus',
|
|
20
|
+
}.fetch(provider.to_sym) { "social-#{provider}" }
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module ShowHelper
|
|
3
|
+
def show_for(model, &block)
|
|
4
|
+
if block_given?
|
|
5
|
+
yield AttributeShower.new(model, self)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class AttributeShower
|
|
10
|
+
attr_reader :object, :helper
|
|
11
|
+
|
|
12
|
+
def initialize(object, helper)
|
|
13
|
+
@object = object
|
|
14
|
+
@helper = helper
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show(attribute)
|
|
18
|
+
render(
|
|
19
|
+
object.class.human_attribute_name(attribute),
|
|
20
|
+
object.send(attribute)
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def render(label, value)
|
|
25
|
+
helper.render('application/show_item', label: label, value: value)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
class City < ActiveRecord::Base
|
|
3
|
+
delegate :to_s, to: :name
|
|
4
|
+
belongs_to :state
|
|
5
|
+
validates :name, presence: true, uniqueness: { case_sensitive: false, scope: :state_id }
|
|
6
|
+
|
|
7
|
+
scope :with_open_jobs, ->{ where(id: Job.open.select(:city_id).uniq) }
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module Filters
|
|
3
|
+
def self.filter(type, params = {})
|
|
4
|
+
filter_class(type).new(params).filter
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.filter_class(type)
|
|
8
|
+
"Recruiter::Filters::#{type.to_s.classify}Filter".constantize
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class Base
|
|
12
|
+
attr_reader :query
|
|
13
|
+
|
|
14
|
+
def self.filter(params = {})
|
|
15
|
+
new(params).filter
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize(params = {})
|
|
19
|
+
init_query
|
|
20
|
+
|
|
21
|
+
params.each do |key, values|
|
|
22
|
+
method = "with_#{key}"
|
|
23
|
+
|
|
24
|
+
if respond_to?(method)
|
|
25
|
+
send(method, *values)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def init_query
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def filter
|
|
34
|
+
query
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def merge(scope = nil, &block)
|
|
38
|
+
@query = query.merge(yield) if block_given?
|
|
39
|
+
@query = query.merge(scope) if scope
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module Filters
|
|
3
|
+
class CityFilter < Base
|
|
4
|
+
def init_query
|
|
5
|
+
@query = City.order('name')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def with_jobs(*args)
|
|
9
|
+
merge(query.where(id: Job.select(:city_id).uniq))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_open_jobs(*args)
|
|
13
|
+
merge(City.with_open_jobs)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def with_state_id(id)
|
|
17
|
+
merge(query.where(state_id: id))
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module Filters
|
|
3
|
+
class JobFilter < Base
|
|
4
|
+
def init_query
|
|
5
|
+
@query = Job.joins(city: :state).includes(city: :state)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def with_open_status(*args)
|
|
9
|
+
merge(Job.open)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_city_id(id)
|
|
13
|
+
merge { query.where(city_id: id) }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def with_state_id(id)
|
|
17
|
+
merge { query.where(recruiter_cities: { state_id: id }) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module Filters
|
|
3
|
+
class StateFilter < Base
|
|
4
|
+
def init_query
|
|
5
|
+
@query = State.order('name')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def with_jobs(*args)
|
|
9
|
+
merge(query.where(id: Job.joins(city: :state).select(:state_id).uniq))
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def with_open_jobs(*args)
|
|
13
|
+
merge(State.with_open_jobs)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
class Job < ActiveRecord::Base
|
|
3
|
+
belongs_to :user
|
|
4
|
+
belongs_to :city
|
|
5
|
+
has_and_belongs_to_many :tags, class_name: 'Recruiter::Tag'
|
|
6
|
+
|
|
7
|
+
validates :user, presence: true
|
|
8
|
+
validates :city, presence: true
|
|
9
|
+
validates :title, presence: true
|
|
10
|
+
validates :description, presence: true
|
|
11
|
+
validates :how_to_apply, presence: true
|
|
12
|
+
|
|
13
|
+
default_scope ->{ order('recruiter_jobs.created_at DESC') }
|
|
14
|
+
scope :open, ->{ where(open: true) }
|
|
15
|
+
|
|
16
|
+
def to_param
|
|
17
|
+
"#{id}-#{title.parameterize}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# form helper
|
|
21
|
+
def state_id=(value)
|
|
22
|
+
@state_id = value
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# form helper
|
|
26
|
+
def state_id
|
|
27
|
+
if @state_id.present?
|
|
28
|
+
@state_id.to_i
|
|
29
|
+
elsif city.present?
|
|
30
|
+
city.state_id
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Recruiter
|
|
2
|
+
module Oauth
|
|
3
|
+
class Base
|
|
4
|
+
def self.provider_key
|
|
5
|
+
to_s.underscore.split('/').last.to_sym
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.find_or_build_user(params)
|
|
9
|
+
user = User.where(uid: params[:uid], provider: provider_key).first
|
|
10
|
+
|
|
11
|
+
unless user
|
|
12
|
+
user = User.new
|
|
13
|
+
user.uid = params[:uid]
|
|
14
|
+
user.provider = provider_key
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
user.provider_data = params
|
|
18
|
+
user.email = params[:info][:email]
|
|
19
|
+
user.name = params[:info][:name]
|
|
20
|
+
user
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|