Commit 3885ed4c by Van Hau Le

Merge branch 'favorite_history' into 'master'

Create Favorite, history job

See merge request !13
parents f95ce8a2 87c62095
Pipeline #1104 canceled with stages
in 0 seconds
.error-banner-ground{
position: relative;
width: 100%;
height: 100vh;
}
.error-500-banner {
background-image: url('500errorpage.jpg');
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
.error-404-banner {
background-image: url('404errorpage.jpg');
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-size: cover;
}
......@@ -47,7 +47,7 @@
.under-descrip {
text-align: center;
}
.apply-btn, .favorite-btn {
.apply-btn, .favorite-btn, .let-favorite {
margin: 20px;
padding: 20px;
}
......
......@@ -42,7 +42,7 @@
margin: 10px;
}
#button-follow{
#button-favorite, #button-unfavorite, #button-remove{
position: absolute;
top: 20%;
right: 5%;
......@@ -133,3 +133,8 @@
transition: 1s;
text-decoration: none;
}
.radio-btn {
position: relative;
top: 150px;
left: 40px;
}
class ApplicationController < ActionController::Base
include SessionsHelper
private
def sign_in_validation
return if signed_in?
store_location
flash[:warning] = Settings.user.warning_signin
redirect_to login_path
end
def render_error_404
respond_to do |format|
format.html { render template: 'errors/error_404', status: 404 }
format.all { render nothing: true, status: 404 }
end
end
def render_error_500
respond_to do |format|
format.html { render template: 'errors/error_500', status: 500 }
format.all { render nothing: true, status: 500 }
end
end
end
......@@ -17,7 +17,10 @@ class AppliedJobsController < ApplicationController
end
def show
@applied_jobs = current_user.job_applieds.order(updated_at: :desc).page(params[:page]).per(Job::LIMIT_PAGE)
@count = current_user.job_applieds.count
return if @count.zero?
@applied_jobs = current_user.job_applieds.includes(job: :cities).order("updated_at DESC").page(params[:page]).per(Job::LIMIT_PAGE)
return render_error_404 if @applied_jobs.blank?
end
def confirmation
......
class FavoriteJobsController < ApplicationController
before_action :sign_in_validation, only: %i[create destroy index]
def index
@count = current_user.favorite_jobs.count
return if @count.zero?
page = Integer(params[:page] || "1") rescue 0
return redirect_to favorite_jobs_path unless page.positive?
@favorited_jobs = current_user.favorite_jobs.includes(job: :cities).order_favorite.page(page).per(Job::LIMIT_PAGE)
return render_error_404 if @favorited_jobs.blank?
end
def create
return if current_user.favorite_jobs.exists?(job_id: params[:job_id])
@favorite = current_user.favorite!(params[:job_id])
respond_to { |format| format.js }
end
def destroy
@unfavorite = current_user.unfavorite!(params[:job_id])
if request.referer.include?("favorite")
@count = current_user.favorite_jobs.count
current_page_count = @count % Job::LIMIT_PAGE
remain_page = @count / Job::LIMIT_PAGE
if current_page_count == Job::DIVISIBLE
return redirect_to favorite_jobs_path(page: remain_page) if params[:page].to_i == remain_page + 1
redirect_to favorite_jobs_path(page: params[:page])
end
end
respond_to { |format| format.js }
end
end
class HistoryJobsController < ApplicationController
before_action :sign_in_validation, only: [:index]
def index
@count = current_user.histories.count
@history_jobs = current_user.histories.includes(job: :cities).order_history
end
end
......@@ -3,24 +3,36 @@ class JobsController < ApplicationController
before_action :general_variables
def index
@count = Job.count
return if @count.zero?
@jobs_list = Job.all.page(params[:page]).per(Job::LIMIT_PAGE)
return render_error_404 if @jobs_list.blank?
end
def city_jobs
@count = City.count
return if @count.zero?
@city = City.find_by(converted_name: params[:converted_name])
@jobs_list = @city.jobs.page(params[:page]).per(Job::LIMIT_PAGE)
return render_error_404 if @jobs_list.blank?
@result_for_job = @city.jobs.count
end
def industry_jobs
@count = Industry.count
return if @count.zero?
@industry = Industry.find_by(converted_name: params[:converted_name])
@jobs_list = @industry.jobs.page(params[:page]).per(Job::LIMIT_PAGE)
return render_error_404 if @jobs_list.blank?
@result_for_job = @industry.jobs.count
end
def company_jobs
@count = Company.count
return if @count.zero?
@company = Company.find_by(converted_name: params[:converted_name])
@jobs_list = @company.jobs.page(params[:page]).per(Job::LIMIT_PAGE)
return render_error_404 if @jobs_list.blank?
@result_for_job = @company.jobs.count
redirect_to jobs_path unless @company
......@@ -30,7 +42,17 @@ class JobsController < ApplicationController
session.delete(:apply_job)
session.delete(:cv)
return redirect_to jobs_path unless @job
@user = JobApplied.where(user_id: current_user.id, job_id: params[:id]) if signed_in?
if signed_in?
@is_job_applied = current_user.job_applieds.pluck(:job_id).include?@job.id
founded_history = current_user.histories.find_by(job_id: params[:id])
return founded_history.update(updated_at: Time.current.utc) if founded_history.present?
history = current_user.histories.create!(job_id: params[:id])
history_jobs = current_user.histories.order_history
history_jobs.last.destroy if history_jobs.count >= Job::LIMIT_HISTORY
end
end
private
......
......@@ -38,13 +38,6 @@ class UsersController < ApplicationController
private
def sign_in_validation
return if signed_in?
store_location
flash[:warning] = Settings.user.warning_signin
redirect_to login_path
end
def user_params
params[:user][:password] = change_pass_param[:new_password] if change_pass_param[:new_password].present?
params.require(:user).permit(:name, :email, :cv_user, :password)
......
......@@ -33,6 +33,7 @@ module SessionsHelper
end
def store_location
return session[:return_to] = request.referer if request.url.include?("favorite_job")
session[:return_to] = request.url if request.get?
end
end
class FavoriteJob < ApplicationRecord
belongs_to :user
belongs_to :job
scope :order_favorite, -> { order(updated_at: :desc) }
end
class History < ApplicationRecord
belongs_to :user
belongs_to :job
scope :order_history, -> { order(updated_at: :desc) }
end
......@@ -18,6 +18,8 @@ class Job < ApplicationRecord
has_many :users, through: :histories
LIMIT_PAGE = 20
LIMIT_HISTORY = 20
DIVISIBLE = 0
scope :limit_job, -> { includes(:cities, :company).order(created_at: :desc).limit(5) }
......@@ -25,6 +27,10 @@ class Job < ApplicationRecord
company&.name
end
def converted_company_name
company&.converted_name
end
def format_desc
description.truncate_words(250)
end
......
......@@ -3,7 +3,7 @@ class User < ApplicationRecord
before_create :create_remember_token
mount_uploader :cv_user, UserCvUploader
has_many :favorite_jobs
has_many :favorite_jobs, foreign_key: "user_id", dependent: :destroy
has_many :jobs, through: :favorite_jobs
has_many :job_applieds
has_many :jobs, through: :job_applieds
......@@ -20,6 +20,22 @@ class User < ApplicationRecord
PASSWORD_FORMAT = /\A(?=.{8,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/x
validates :password, format: { with: PASSWORD_FORMAT, message: "is too short or not strength" }
def favoriting?(job_id)
favorite_jobs.find_by(job_id: job_id)
end
def favorite!(job_id)
favorite_jobs.create!(job_id: job_id)
end
def unfavorite!(job_id)
favorite_jobs.find_by(job_id: job_id)&.destroy
end
def remove_history!(job_id)
histories.find_by(job_id: job_id)&.destroy
end
def self.new_remember_token
SecureRandom.urlsafe_base64
end
......
<div class="container">
<% if @applied_jobs.count > 0 %>
<% if @count > 0 %>
<h1 class="text-center my-job-label">My Job</h1>
<%= paginate @applied_jobs, outer_window: 2, window: 1 %>
<%= render partial: "job_applieds/my_jobs", collection: @applied_jobs, as: :applied_job %>
<%= render partial: "applied_jobs/my_jobs", collection: @applied_jobs, as: :applied_job %>
<%= paginate @applied_jobs, outer_window: 2, window: 1 %>
<% else %>
<h1 class="let-apply">Let's apply job</h1>
......
<div class="container">
<div class="error-banner-ground">
<div class="error-404-banner">
</div>
</div>
</div>
<div class="container">
<div class="error-banner-ground">
<div class="error-500-banner">
</div>
</div>
</div>
<div class="job-id-<%= favorite_job.job.id %>">
<div class="border border-dark rounded">
<div class="row">
<div class="radio-btn col-1">
<%= radio_button_tag :job_id, favorite_job.job.id %>
</div>
<div class="job-details col-10">
<div class="title">
<%= link_to job_detail_path(favorite_job.job.id) do %><strong>
<%= favorite_job.job.title %></strong>
<% end %>
</div>
<div class="row">
<div class="introduction col-10">
<%= strip_tags(favorite_job.job.format_desc) %><br>
<%= link_to 'Read more..', job_detail_path(favorite_job.job.id) %>
</div>
<div class="col-6">
<%= favorite_job.job.cities.map(&:name).join(' | ') %>
</div>
<div class="salary col-3">
Salary: <%= favorite_job.job.salary %>
</div>
<%= link_to "Remove", unfavorite_job_path(job_id: favorite_job.job.id, page: params[:page] || "1"), method: :delete, remote: true, class: "btn btn-danger", id: "button-remove" %>
</div>
</div>
</div>
</div>
</div>
<br>
$("#favorite-form-<%= @favorite.job_id %>").html("<%=escape_javascript render 'users/unfavorite', job_id: @favorite.job_id %>");
$("#favorite-form-<%= @unfavorite.job_id %>").html("<%= j render 'users/favorite', job_id: @unfavorite.job_id %>");
$(".job-id-<%= @unfavorite.job_id %>").remove();
$(".count-favorite-jobs").html("<%= @count %>");
<div class="container">
<% if @count > 0 %>
<h1 class="text-center my-job-label">Favorite Job (<span class="count-favorite-jobs"><%= @count %></span> jobs)</h1>
<%= paginate @favorited_jobs, outer_window: 2, window: 1 %>
<div class="favorite-page">
<%= form_tag apply_job_path(job_id: params[:job_id]), method: :get, enforce_utf8: false do %>
<%= render partial: "favorite_jobs/favorite_job", collection: @favorited_jobs %>
<div class="row justify-content-center apply-btn">
<%= submit_tag 'Apply Job', name: nil, class: 'btn btn-lg btn-danger' %>
</div>
<% end %>
</div>
<%= paginate @favorited_jobs, outer_window: 2, window: 1 %>
<% else %>
<h1 class="let-favorite">Let's Favorite Job</h1>
<% end %>
</div>
<div class="job-id-<%= history_job.job.id %>">
<div class="border border-dark rounded">
<div class="row">
<div class="radio-btn col-1">
<%= radio_button_tag :job_id, history_job.job.id %>
</div>
<div class="job-details col-10">
<div class="title">
<%= link_to job_detail_path(history_job.job.id) do %><strong>
<%= history_job.job.title %></strong>
<% end %>
</div>
<div class="row">
<div class="introduction col-12">
<%= strip_tags(history_job.job.format_desc) %><br>
<%= link_to 'Read more..', job_detail_path(history_job.job.id) %>
</div>
<div class="col-6">
<%= history_job.job.cities.map(&:name).join(' | ') %>
</div>
<div class="salary col-6">
Salary: <%= history_job.job.salary %>
</div>
</div>
</div>
</div>
</div>
</div>
<br>
<div class="container">
<% if @count > 0 %>
<h1 class="text-center my-job-label">History(<span class="count-histories-jobs"><%= @count %></span> jobs)</h1>
<div class="history-page">
<%= form_tag apply_job_path(job_id: params[:job_id]), method: :get, enforce_utf8: false do %>
<%= render partial: "history_jobs/history_job", collection: @history_jobs %>
<div class="row justify-content-center apply-btn">
<%= submit_tag 'Apply Job', name: nil, class: 'btn btn-lg btn-danger' %>
</div>
<% end %>
</div>
<% else %>
<h1 class="let-favorite">Your History doesn't have jobs</h1>
<% end %>
</div>
......@@ -16,7 +16,11 @@
<%= link_to 'Read more..', job_detail_path(job.id) %>
</div>
</div>
<button type="button" class="btn btn-success" id="button-follow">♥ Favorite</button>
<% if signed_in? %>
<%= render partial: 'users/favorite_form', locals: { job: job } %>
<% else %>
<%= render 'users/favorite', job_id: job.id %>
<% end %>
</div>
</div>
<br>
......
<% provide(:title, 'City Jobs') %>
<div class="container">
<% if @count > 0 %>
<div class="search-bar">
<%= render 'layouts/search_bar' %>
</div>
......@@ -11,4 +12,7 @@
<%= render partial: "job", collection: @jobs_list, as: :job %>
</div>
<%= render "jobs/pagination" %>
<% else %>
<h1>Don't have city</h1>
<% end %>
</div>
<% provide(:title, 'Company Jobs') %>
<div class="container">
<% if @count > 0 %>
<div class="search-bar">
<%= render 'layouts/search_bar' %>
</div>
......@@ -11,4 +12,7 @@
<%= render partial: "job", collection: @jobs_list, as: :job %>
</div>
<%= render "jobs/pagination" %>
<% else %>
<h1>Don't have company</h1>
<% end %>
</div>
<% provide(:title, 'Jobs') %>
<div class="container">
<% if @count > 0 %>
<%= render 'layouts/flash' %>
<div class="search-bar">
<%= render 'layouts/search_bar' %>
......@@ -12,4 +13,7 @@
<%= render partial: "job", collection: @jobs_list, as: :job %>
</div>
<%= render "jobs/pagination" %>
<% else %>
<h1>Don't have job</h1>
<% end %>
</div>
<% provide(:title, 'Industry Jobs') %>
<div class="container">
<% if @count > 0 %>
<div class="search-bar">
<%= render 'layouts/search_bar' %>
</div>
......@@ -11,4 +12,7 @@
<%= render partial: "job", collection: @jobs_list, as: :job %>
</div>
<%= render "jobs/pagination" %>
<% else %>
<h1>Don't have industry</h1>
<% end %>
</div>
......@@ -5,7 +5,7 @@
<div class="job-info">
<div><strong><%= @job.title %></strong></div>
<div>
<%= link_to @job.company_name, company_jobs_path(converted_name: @job.company.converted_name), class: 'company' %>
<%= link_to @job.company_name, company_jobs_path(converted_name: @job.converted_company_name), class: 'company' %>
</div>
<div class="breadcrumb">
<%= link_to "TOP", root_path %>&ensp;/&ensp;
......@@ -19,7 +19,7 @@
<% end %>/&ensp;
<%= @job.title.truncate_words(5) %>
</div>
<% if signed_in? && @user.present? %>
<% if @is_job_applied %>
<div class="apply-job">
<strong>Applied</strong>
</div>
......@@ -76,22 +76,22 @@
<div class="row under-descrip">
<div class="col-6">
<% if signed_in? && @user.present? %>
<div class="btn btn-info btn-lg apply-btn">
<div class="btn btn-info apply-btn">
<strong>Applied</strong>
</div>
<% else %>
<%= link_to apply_job_path(job_id: @job.id) do %>
<div class="btn btn-info btn-lg apply-btn">
<div class="btn btn-info apply-btn">
<strong>Apply Now</strong>
</div>
<% end %>
<% end %>
</div>
<div class="col-6">
<%= link_to '#' do %>
<div class="btn btn-danger btn-lg favorite-btn">
<strong>Favorite</strong>
</div>
<div class="col-3">
<% if signed_in? %>
<%= render partial: 'users/favorite_form', locals: { job: @job } %>
<% else %>
<%= render 'users/favorite', job_id: @job.id %>
<% end %>
</div>
</div>
......
......@@ -11,8 +11,8 @@
<li><%= link_to "Log In", login_path , class: "nav-item nav-link" %></li>
<li><%= link_to "Register", register_step1_path, class: "nav-item nav-link" %></li>
<% end %>
<li><%= link_to "Favorite", '#', class: "nav-item nav-link" %></li>
<li><%= link_to "History", '#', class: "nav-item nav-link" %></li>
<li><%= link_to "Favorite", favorite_jobs_path, class: "nav-item nav-link" %></li>
<li><%= link_to "History", history_jobs_path, class: "nav-item nav-link" %></li>
</ul>
</nav>
</div>
......
......@@ -9,7 +9,7 @@
<%= render 'layouts/search_bar' %>
</div>
<div class="job-list">
<%= render partial: "layouts/show_job", collection: @jobs, as: :job %>
<%= render partial: "users/show_job", collection: @jobs, as: :job %>
</div>
<div class="city-banner rounded">City</div>
......
<%= form_for(:job_favorite, url: favorite_job_path(job_id: job_id), method: :post, remote: true) do |f| %>
<%= f.submit "Favorite", class: "btn btn-danger", id: "button-favorite" %>
<% end %>
<div id="favorite-form-<%= job.id %>">
<% if current_user.favoriting?(job.id) %>
<%= render 'users/unfavorite', job_id: job.id %>
<% else %>
<%= render 'users/favorite', job_id: job.id %>
<% end %>
</div>
......@@ -17,7 +17,11 @@
<%= link_to 'Read more..', job_detail_path(job.id) %>
</div>
</div>
<button type="button" class="btn btn-primary" id="button-follow">♥ Follow</button>
<% if signed_in? %>
<%= render partial: 'users/favorite_form', locals: { job: job } %>
<% else %>
<%= render 'users/favorite', job_id: job.id %>
<% end %>
</div>
</div>
<br>
......
<%= form_for(:job_unfavorite, url: unfavorite_job_path(job_id: job_id), method: :delete, remote: true, data: { disable_with: false }) do |f| %>
<%= f.submit "Unfavorite", class: "btn btn-outline-danger", id: "button-unfavorite" %>
<% end %>
......@@ -10,6 +10,7 @@ module Venjob
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.exceptions_app = self.routes
config.before_configuration do
env_file = File.join(Rails.root, 'config', 'local_env.yml')
YAML.load(File.open(env_file)).each do |key, value|
......
......@@ -10,7 +10,7 @@ Rails.application.configure do
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
config.consider_all_requests_local = false
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
......
......@@ -26,13 +26,21 @@ Rails.application.routes.draw do
get '/my/jobs', to: 'applied_jobs#show', as: :my_jobs
resources :jobs
resources :jobsgits
get 'detail/:id', to: 'jobs#show', as: :job_detail
get 'jobs/city/:converted_name', to: 'jobs#city_jobs', as: :city_jobs
get 'jobs/industry/:converted_name', to: 'jobs#industry_jobs', as: :industry_jobs
get 'jobs/company/:converted_name', to: 'jobs#company_jobs', as: :company_jobs
post 'favorite_job', to: 'favorite_jobs#create', as: :favorite_job
delete 'unfavorite_job', to: 'favorite_jobs#destroy', as: :unfavorite_job
get 'favorite', to: 'favorite_jobs#index', as: :favorite_jobs
get 'history', to: 'history_jobs#index', as: :history_jobs
resources :history_jobs, only: [:index]
resources :favorite_jobs, only: [:create, :destroy, :index]
resources :applied_jobs, only: [:new, :create]
resources :reset_passwords, only: [:edit, :update]
resources :confirmations, only: [:new]
......@@ -40,6 +48,9 @@ Rails.application.routes.draw do
resources :industries, only: [:index]
resources :cities, only: [:index]
root to: "top_pages#index"
match '/404', via: :all, to: 'errors#error_404'
match '/500', via: :all, to: 'errors#error_500'
end
......@@ -21,6 +21,9 @@ user:
applied_job:
applied: 'You applied for this job'
favorite_job:
validate_page: 'Params Page format failed'
email:
confirmation: 'Welcome To VeNJOB! Confirm Your Email'
reset_password: 'VeNJOB Password Assistance'
......
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