Commit 8450f8c6 by Hoang Phuc

Merge branch 'master' of gitlab.zigexn.vn:phucth/ven-job into feature/solr_management

parents 0dad2f5e 2caeabd0
Pipeline #591 failed with stages
in 0 seconds
......@@ -26,6 +26,9 @@ gem 'bcrypt', '~> 3.1.7'
gem 'devise'
gem 'rsolr'
gem 'carrierwave'
gem 'activerecord-import'
gem 'settingslogic'
......
......@@ -77,6 +77,13 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (~> 1.5)
xpath (~> 3.2)
carrierwave (2.1.0)
activemodel (>= 5.0.0)
activesupport (>= 5.0.0)
addressable (~> 2.6)
image_processing (~> 1.1)
mimemagic (>= 0.3.0)
mini_mime (>= 0.1.3)
childprocess (3.0.0)
coderay (1.1.2)
concurrent-ruby (1.1.6)
......@@ -98,6 +105,9 @@ GEM
activesupport (>= 4.2.0)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
image_processing (1.10.3)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
jbuilder (2.10.0)
activesupport (>= 5.0.0)
kaminari (1.2.0)
......@@ -125,6 +135,7 @@ GEM
mimemagic (~> 0.3.2)
method_source (1.0.0)
mimemagic (0.3.4)
mini_magick (4.10.1)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
......@@ -201,6 +212,8 @@ GEM
rsolr (2.3.0)
builder (>= 2.1.2)
faraday (>= 0.9.0)
ruby-vips (2.0.17)
ffi (~> 1.9)
ruby_dep (1.5.0)
rubyzip (2.3.0)
sass-rails (6.0.0)
......@@ -282,6 +295,7 @@ DEPENDENCIES
bootsnap (>= 1.4.2)
byebug
capybara (>= 2.15)
carrierwave
devise
jbuilder (~> 2.7)
kaminari
......
......@@ -92,6 +92,9 @@ ul.job_listings .job_listing:hover, .job_position_featured, li.type-resume:hover
background-color: transparent;
border-color: #7dc246;
}
input[type=button].application_button:disabled{
cursor: not-allowed;
}
.button--type-action:hover, .button--type-secondary, .single-product #content .single_add_to_cart_button:hover, .checkout-button:hover, #place_order:hover, input[type=button].application_button:hover, .application_button_link:hover, input[type=button].resume_contact_button:hover {
background-color: #7dc246;
......
......@@ -10,20 +10,81 @@
$(".back2top").click(function(){
$("html, body").animate({scrollTop: 0}, 500);
})
$(".job_application .application_button").click(function (e) {
$(".apply-or-favorite-jobs").click(function (e) {
e.preventDefault()
data = { job_ids: [$(this).data("id")] }
data = {
job_ids: [$(this).data("id")],
type: $(this).data("type")
}
$.ajax({
url: '/job/apply',
url: '/apply_or_favorite',
data: data,
type: 'POST',
success: (res) => {
console.log("response: ", res)
alert(res.message)
},
error: (err) => {
console.log("error: ", err)
if(err.status === 401){
if(confirm(err.responseJSON.message)){
window.location.href = "/users/sign_in";
}
}
}
});
})
$(".apply-all-job").click(function (e) {
e.preventDefault()
if($(".checkbox-apply-job:checked").length === 0){
alert("Please choose jobs need apply!")
return;
}
data = {
job_ids: [],
type: 'apply'
}
$(".checkbox-apply-job:checked").each(function() {
data.job_ids.push($(this).data("id"))
})
$.ajax({
url: '/apply_or_favorite',
data: data,
type: 'POST',
success: (res) => {
alert(res.message)
location.reload()
},
error: (err) => {
if(err.status === 401){
if(confirm(err.responseJSON.message)){
window.location.href = "/users/sign_in";
}
}
}
});
})
$(".remove-favorite-job").click(function (e) {
e.preventDefault()
if(confirm("Are you sure?")){
data = {
favorite_id: $(this).data("favorite_id")
}
$.ajax({
url: '/remove_favorite_job',
data: data,
type: 'DELETE',
success: (res) => {
alert(res.message)
location.reload()
},
error: (err) => {
if(err.status === 401){
if(confirm(err.responseJSON.message)){
window.location.href = "/users/sign_in";
}
}
}
});
}
})
})(jQuery);
\ No newline at end of file
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:full_name])
devise_parameter_sanitizer.permit(:account_update, keys: [:full_name, :cv])
end
end
......@@ -18,6 +18,10 @@ class JobsController < ApplicationController
@job = Job.find_by(id: params[:id])
if @job.present?
@title = @job.title
if user_signed_in?
@apply = Apply.find_by(job_id: params[:id], user_id: current_user.id)
@favorite = Favorite.find_by(job_id: params[:id], user_id: current_user.id)
end
@relate_jobs = Job.where("company_id = ? and id != ?", @job.company_id, @job.id).order("id DESC")
if cookies[:job_ids_history].nil?
cookies[:job_ids_history] = {value: @job.id, expires: Time.now + 3600}
......@@ -35,7 +39,4 @@ class JobsController < ApplicationController
@title = "Job was not found"
end
end
def apply_jobs
end
end
class UsersController < ApplicationController
def info
unless user_signed_in?
redirect_to '/users/sign_in'
end
end
def apply_jobs
unless user_signed_in?
redirect_to '/users/sign_in'
else
@applied_jobs = Apply.where("user_id = ?", current_user.id)
end
end
def favorite_jobs
unless user_signed_in?
redirect_to '/users/sign_in'
else
@favorite_jobs = Favorite.where("user_id = ?", current_user.id)
end
end
def apply_or_favorite_jobs
unless user_signed_in?
payload = {
message: "You are not logged in, please login to operate the feature",
}
render :json => payload, :status => :unauthorized
else
if params[:job_ids].present?
params[:job_ids].each do |id|
if params[:type] == "apply"
Apply.find_or_create_by({:user_id => current_user.id, :job_id => id})
else
Favorite.find_or_create_by({:user_id => current_user.id, :job_id => id})
end
end
payload = {
message: "Thank you for #{params[:type] == "apply" ? "applied" : "favourited"} with VenJob",
}
render :json => payload, :status => :ok
end
end
end
def remove_favorite_job
unless user_signed_in?
payload = {
message: "You are not logged in, please login to operate the feature",
}
render :json => payload, :status => :unauthorized
else
if params[:favorite_id].present?
Favorite.find_by(id: params[:favorite_id]).destroy
payload = {
message: "Remove successfully"
}
render :json => payload, :status => :ok
end
end
end
end
......@@ -8,4 +8,6 @@ class User < ApplicationRecord
has_many :jobs, through: :applies
has_many :favorites
has_many :jobs, through: :favorites
mount_uploader :cv, CvUploader
end
class CvUploader < 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(*args)
# # 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_whitelist
%w(pdf doc xls xlsx zip)
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
......@@ -11,7 +11,7 @@
<p class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
<%= f.email_field :email, autofocus: true, autocomplete: "email", placeholder: "Email" %>
</p>
<p class="actions">
......
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<% content_for :title, "VenJob - Edit #{resource_name.to_s.humanize}" %>
<header class="page-header">
<h2 class="page-title">Edit <%= resource_name.to_s.humanize %></h2>
</header>
<div id="primary" class="content-area container" role="main">
<article id="post-1673" class="post-1673 page type-page status-publish hentry">
<div class="entry-content">
<div class="registration-form woocommerce">
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<p class="field">
<%= f.label :full_name %><br />
<%= f.text_field :full_name, placeholder: "Fullname" %>
</p>
<p class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<%= f.email_field :email, placeholder: "Email" %>
</p>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<p>Currently waiting confirmation for: <%= resource.unconfirmed_email %></p>
<% end %>
<div class="field">
<p class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "new-password" %>
<%= f.password_field :password, autocomplete: "new-password", placeholder: "Password" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>
</p>
<div class="field">
<p class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>
<%= f.password_field :password_confirmation, autocomplete: "new-password", placeholder: "Confirm password" %>
</p>
<div class="field">
<p class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "current-password" %>
</div>
<%= f.password_field :current_password, autocomplete: "current-password", placeholder: "Current password" %>
</p>
<div class="actions">
<%= f.submit "Update" %>
<fieldset class="fieldset-featured_image fieldset-type-file">
<%= f.label :cv %>
<div class="field ">
<label for="user_cv" class="file-field-label">
<div class="job-manager-uploaded-files">
</div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<%= f.file_field :cv, accept: "application/pdf,.xls,.xlsx,.doc,.zip" %>
<span class="button button--size-medium">
Choose file
</span>
</label>
<small class="description file-field-description">
Allowed format: doc, pdf, xls, xlsx, zip. Maxium size: 5MB.
</small>
</div>
</fieldset>
<%= link_to "Back", :back %>
<p class="actions" style="text-align: center;">
<%= f.submit "Update", class: "button" %>
</p>
<% end %>
</div>
</div>
</article>
</div>
\ No newline at end of file
......@@ -10,8 +10,13 @@
<%= render "devise/shared/error_messages", resource: resource %>
<p class="field">
<%= f.label :full_name %><br />
<%= f.text_field :full_name, autofocus: true, autocomplete: "full_name" %>
</p>
<p class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
<%= f.email_field :email, autocomplete: "email" %>
</p>
<p class="field">
......
......@@ -24,10 +24,10 @@
<%= index + 1%>
</td>
<td style="text-align: center;">
<input type="checkbox">
<input type="checkbox" class="checkbox-apply-job" data-id="<%= job.id %>">
</td>
<td>
<%= job.title %>
<%= link_to job.title, job %>
</td>
<td>
<% job.cities.each_with_index do |city, index| %>
......@@ -37,14 +37,11 @@
<td class="product-price">
<%= job.salary %>
</td>
<td class="product-quantity">
</td>
</tr>
<% end %>
<tr>
<td colspan="6" class="actions">
<button type="submit" class="button" name="update_cart" value="Update cart" >Apply all</button>
<a class="button apply-all-job" href="javascript:void(0)">Apply all</a>
</td>
</tr>
</tbody>
......
......@@ -32,11 +32,19 @@
<img class="company_logo" src="<%= @job.company.logo != "" ? @job.company.logo : "https://via.placeholder.com/66x38?text=Logo" %>" alt="<%= @job.company.title %>" />
</aside>
<aside class="widget widget--job_listing">
<div class="job_application application">
<input type="button" class="application_button button" value="Apply for job" />
<div class="job_application application" style="margin-bottom: 15px;">
<% unless @apply.present? %>
<input type="button" class="application_button button apply-or-favorite-jobs" value="Apply for job" data-id="<%= @job.id %>" data-type="apply"/>
<% else %>
<input type="button" class="application_button button" value="Apply for job" disabled/>
<% end %>
</div>
<div class="job-manager-form wp-job-manager-bookmarks-form">
<a class="bookmark-notice" href="https://jobify-demos.astoundify.com/classic/account/">Favorite</a>
<div class="job_application application">
<% unless @favorite.present? %>
<input type="button" class="application_button button apply-or-favorite-jobs" value="Favorite" data-id="<%= @job.id %>" data-type="favorite"/>
<% else %>
<input type="button" class="application_button button" value="Favorite" disabled/>
<% end %>
</div>
</aside>
<aside class="widget widget--job_listing">
......
......@@ -49,6 +49,12 @@
<a href="/history">History</a>
</li>
<% if current_user %>
<li class="register menu-item menu-item-type-post_type menu-item-object-page menu-item-99991219">
<%= link_to 'Favorite', users_favorite_jobs_path %>
</li>
<li class="register menu-item menu-item-type-post_type menu-item-object-page menu-item-99991219">
<%= link_to 'Hi, ' + current_user.full_name, users_info_path %>
</li>
<li class="login menu-item menu-item-type-post_type menu-item-object-page menu-item-99991213">
<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>
</li>
......
<% content_for :title, "VenJob - Appied Jobs" %>
<header class="page-header">
<h2 class="page-title">Appied Jobs</h2>
</header>
<div id="primary" class="content-area container" role="main">
<article id="post-1673" class="post-1673 page type-page status-publish hentry">
<div class="entry-content">
<div class="woocommerce">
<div class="woocommerce-notices-wrapper"></div>
<% if @applied_jobs.present? %>
<table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0">
<thead>
<tr>
<th class="product-remove">No.</th>
<th class="product-thumbnail">&nbsp;</th>
<th class="product-name">Title</th>
<th class="product-price">City</th>
<th class="product-quantity">Salary</th>
<th class="product-quantity">Applied at</th>
</tr>
</thead>
<tbody>
<% @applied_jobs.each_with_index do |apply, index| %>
<tr class="woocommerce-cart-form__cart-item cart_item">
<td>
<%= index + 1%>
</td>
<td>
</td>
<td>
<%= apply.job.title %>
</td>
<td>
<% apply.job.cities.each_with_index do |city, index| %>
<%= city.title %><%= ", " if index != apply.job.cities.size - 1 %>
<% end %>
</td>
<td class="product-price">
<%= apply.job.salary %>
</td>
<td class="product-quantity">
<%= apply.created_at.strftime("%F %T") %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
Applied jobs empty
<% end %>
</div>
</div>
</article>
</div>
\ No newline at end of file
<%= content_for :title, "VenJob - Favorite jobs" %>
<header class="page-header">
<h2 class="page-title">Favorite jobs</h2>
</header>
<div id="primary" class="content-area container" role="main">
<article id="post-2452" class="post-2452 page type-page status-publish hentry">
<div class="entry-content">
<div class="woocommerce">
<div class="woocommerce-notices-wrapper"></div>
<% if @favorite_jobs.present? %>
<table class="shop_table shop_table_responsive cart woocommerce-cart-form__contents" cellspacing="0">
<thead>
<tr>
<th class="product-remove">No.</th>
<th class="product-thumbnail">&nbsp;</th>
<th class="product-name">Title</th>
<th class="product-price">City</th>
<th class="product-quantity">Salary</th>
<th class="product-quantity">Remove</th>
</tr>
</thead>
<tbody>
<% @favorite_jobs.each_with_index do |favorite, index| %>
<tr class="woocommerce-cart-form__cart-item cart_item">
<td>
<%= index + 1%>
</td>
<td style="text-align: center;">
<input type="checkbox" class="checkbox-apply-job" data-id="<%= favorite.job_id %>">
</td>
<td>
<%= link_to favorite.job.title, favorite.job %>
</td>
<td>
<% favorite.job.cities.each_with_index do |city, index| %>
<%= city.title %><%= ", " if index != favorite.job.cities.size - 1 %>
<% end %>
</td>
<td class="product-price">
<%= favorite.job.salary %>
</td>
<td class="product-quantity">
<a href="javascript:void(0)" class="remove-favorite-job" data-favorite_id="<%= favorite.id %>">×</a>
</td>
</tr>
<% end %>
<tr>
<td colspan="6" class="actions">
<a class="button apply-all-job" href="javascript:void(0)">Apply all</a>
</td>
</tr>
</tbody>
</table>
<% else %>
Favorite jobs empty
<% end %>
</div>
</div>
</article>
</div>
<% content_for :title, "VenJob - User info" %>
<header class="page-header">
<h2 class="page-title">User info</h2>
</header>
<div id="primary" class="content-area container" role="main">
<article id="post-1673" class="post-1673 page type-page status-publish hentry">
<div class="entry-content">
<form id="submit-job-form" class="job-manager-form">
<fieldset>
<label for="full_name">Fullname</label>
<div class="field required-field draft-required">
<input type="text" class="input-text" name="full_name" id="full_name" value="<%= current_user.full_name %>" disabled >
</div>
</fieldset>
<fieldset>
<label for="email">Email</label>
<div class="field required-field draft-required">
<input type="email" class="input-text" name="email" id="email" value="<%= current_user.email %>" disabled >
</div>
</fieldset>
<fieldset>
<label for="cv">CV</label>
<div class="field required-field draft-required">
<a href="<%= current_user.cv %>" target="_blank"><%= current_user.cv %></a>
</div>
</fieldset>
<p>
<%= link_to "Update", edit_user_registration_path, class: "button" %>
<%= link_to "My jobs", users_applied_jobs_path, class: "button" %>
</p>
</form>
</div>
</article>
</div>
\ No newline at end of file
......@@ -11,6 +11,11 @@ Rails.application.routes.draw do
get '/cities/', to: 'cities#index', as: 'cities'
get '/industries/', to: 'industries#index', as: 'industries'
get '/history/', to: 'history#index'
get '/users/info', to: 'users#info'
get '/users/applied-jobs', to: 'users#apply_jobs'
get '/users/favorite-jobs', to: 'users#favorite_jobs'
post 'job/apply', to: 'job#apply_jobs'
post '/apply_or_favorite', to: 'users#apply_or_favorite_jobs'
delete 'remove_favorite_job', to: 'users#remove_favorite_job'
end
class AddColumnsToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :full_name, :string
add_column :users, :cv, :string
end
end
......@@ -88,6 +88,8 @@ ActiveRecord::Schema.define(version: 2020_04_23_044651) do
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "full_name"
t.string "cv"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment