Commit d410c980 by Hoang Nam Nguyen

'Finish admin page'

parent ae5c94d7
class AdminController < ApplicationController
before_action :search_params, only: [:search_user_applied, :download_csv]
def admin
end
def login_admin
@admin = Admin.find_by(email: params[:session][:email].downcase)
if @admin && @admin.authenticate(params[:session][:password])
login @admin
redirect_to applied_user_path
else
flash[:danger] = 'Invalid email/password combination'
redirect_to login_form_path
end
end
def signout_admin
logout_admin
redirect_to root_path
end
def applied_user_jobs
@apply_job = Apply.recent_applied.page(params[:page]).per(5)
end
def search_user_applied
search_params = params[:session]
@all_apply = Apply.all
@apply = Apply.joins(:user).joins(job: [:job_industries, :job_cities])
@applies = @apply.where(users: { email: search_params[:email] }) if search_params[:email].present?
@applies = @apply.where(job_industries: { industry_id: search_params[:industry_id] }) if search_params[:industry_id].present?
@applies = @apply.where(job_cities: { city_id: search_params[:city_id] }) if search_params[:city_id].present?
if params[:date][:start_date].present? && params[:date][:end_date].present?
start_date = Date.parse(params[:date][:start_date])
end_date = Date.parse(params[:date][:end_date])
@applies = @apply.where(jobs: {expiry_date: start_date..end_date})
end
if @applies.present?
@applies = @applies.uniq
return send_data(Apply.to_csv(@applies), :filename => 'file.csv') if params[:downloadcv].present?
render 'search_after'
else
flash[:danger] = "You not search"
render 'nil_search'
end
end
private
def search_params
return search_user_applied
end
end
\ No newline at end of file
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery with: :exception protect_from_forgery with: :exception
include SessionsHelper include SessionsHelper
# include AppliesHelper include AdminHelper
end end
class UsersController < ApplicationController class UsersController < ApplicationController
before_action :check_register_expiration, only: [:edit, :update]
def new def new
@user = User.new @user = User.new
...@@ -9,6 +10,7 @@ class UsersController < ApplicationController ...@@ -9,6 +10,7 @@ class UsersController < ApplicationController
@user.validate_name = false @user.validate_name = false
@user.validate_password = false @user.validate_password = false
if @user.save if @user.save
@user.create_activation_digest
flash[:success] = "Please confirm your email" flash[:success] = "Please confirm your email"
UserMailer.welcome_email(@user.id).deliver_later UserMailer.welcome_email(@user.id).deliver_later
render 'show' render 'show'
...@@ -62,6 +64,14 @@ class UsersController < ApplicationController ...@@ -62,6 +64,14 @@ class UsersController < ApplicationController
:password_confirmation, :cv) :password_confirmation, :cv)
end end
def check_register_expiration
@user = User.find(params[:id])
if @user.register_expired?
flash[:danger] = "Register has expired"
redirect_to confirm_email_path
end
end
def email_params def email_params
params.require(:user).permit(:email) params.require(:user).permit(:email)
end end
......
module AdminHelper
def login(admin)
session[:admin_id] = admin.id
end
def current_admin
@current_admin ||= Admin.find_by(id: session[:admin_id])
end
def logged_admin?
!current_admin.nil?
end
def logout_admin
session.delete(:admin_id)
@current_admin = nil
end
end
class Admin < ApplicationRecord
has_many :users
before_save { self.email = email.downcase }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email,presence: true,length: {maximum: 255},
format: {with: VALID_EMAIL_REGEX },
uniqueness: {case_sensitive: false}
validates :password,presence: true,length: {minimum: 6}
has_secure_password(validations: false)
with_options unless: :new_record? do |opts|
opts.validates :password, presence: true, length: { maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED,minimum: 6 }
opts.validates_confirmation_of :password, allow_blank: true
end
def digest(string)
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
BCrypt::Engine.cost
BCrypt::Password.create(string, cost: cost)
end
end
require 'csv'
class Apply < ApplicationRecord class Apply < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :job belongs_to :job
...@@ -6,4 +7,17 @@ class Apply < ApplicationRecord ...@@ -6,4 +7,17 @@ class Apply < ApplicationRecord
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: {maximum: 255}, validates :email, presence: true, length: {maximum: 255},
format: {with: VALID_EMAIL_REGEX} format: {with: VALID_EMAIL_REGEX}
scope :recent_applied, -> { order(updated_at: :desc) }
def self.to_csv(applies)
CSV.generate(headers: true) do |csv|
applies.each do |apply|
job_name = apply.job.job_title
job_salary = apply.job.salary
job_description = apply.job.descripton
csv << [job_name, job_description, job_salary]
end
end
end
end end
...@@ -30,7 +30,9 @@ class User < ApplicationRecord ...@@ -30,7 +30,9 @@ class User < ApplicationRecord
def create_reset_digest def create_reset_digest
self.reset_token = generate_token self.reset_token = generate_token
update_attributes(:reset_digest => digest(reset_token),:reset_sent_at => Time.zone.now) self.reset_digest = digest(reset_token)
self.reset_sent_at = Time.zone.now
save(validate: false)
end end
def digest(string) def digest(string)
...@@ -53,6 +55,10 @@ class User < ApplicationRecord ...@@ -53,6 +55,10 @@ class User < ApplicationRecord
reset_sent_at < 1.day.ago reset_sent_at < 1.day.ago
end end
def register_expired?
created_at < 1.day.ago
end
def applied_job?(job) def applied_job?(job)
applies.pluck(:job_id).include?(job.id) applies.pluck(:job_id).include?(job.id)
end end
...@@ -69,17 +75,17 @@ class User < ApplicationRecord ...@@ -69,17 +75,17 @@ class User < ApplicationRecord
favorites.find_by(job_id: job_id).destroy favorites.find_by(job_id: job_id).destroy
end end
def create_activation_digest
self.activation_token = generate_token
self.activation_digest = digest(activation_token)
end
private private
def downcase_email def downcase_email
self.email = email.downcase self.email = email.downcase
end end
def create_activation_digest
self.activation_token = generate_token
self.activation_digest = digest(activation_token)
end
def generate_token def generate_token
SecureRandom.urlsafe_base64 SecureRandom.urlsafe_base64
end end
......
<div class="container mt-5" >
<div class="row mb-5 ml-5">
<div class="search_list titlejob col-md-10">
<%= link_to apply.job.job_title, job_detail_path(apply.job.id),class: 'search_list_jobs_title' %>
<li class="detail_description text-danger">
<strong><%= apply.user.name %></strong>
</li>
<div class="row ml-0">
<li class="detail_description col-md-10">
<%= link_to apply.user.cv,downloadcv_path(id: apply.user.id) %>
</li>
<li class="detail_description col-md-5">
<%= apply.user.email%>
</li>
<li class=" detail_description float-right text-danger col-md-5">
<%= apply.updated_at%>
</li>
<li class="detail_description col-md-10">
<%= apply.job.expiry_date %>
</li>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="row mt-3">
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :email %></i></strong>
</div>
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-user fa" aria-hidden="true"></i></span>
<%= f.email_field :email, class: 'form-control mb-5' %>
</div>
</div>
<div class="col-md-2">
<strong><i class="text-danger"><%= f.label :password, "Password" %></i></strong>
</div>
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-lock" aria-hidden="true"></i></span>
<%= f.password_field :password, class: 'form-control' %>
</div>
</div>
</div>
<div class="row ml-5 text-center mt-5">
<div class="col-md-12 ml-5">
<%= button_tag(type: "submit", class: "btn btn-lg btn-danger btn-block") do %>
<span class="fa fa-sign-in"></span> Log In
<% end %>
</div>
</div>
\ No newline at end of file
<div class="row mt-3">
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :email %></i></strong>
</div>
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-envelope" aria-hidden="true"></i></span>
<%= f.email_field :email, class: 'form-control mb-5' %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :city_id %></i></strong>
</div>
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-university" aria-hidden="true"></i></span>
<%= f.collection_select :city_id, City.order(:location), :id, :location, {prompt: "Select a City"}, {class: "form-control mb-5"} %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :industry_id %></i></strong>
</div>
<div class="col-md-10">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-shopping-bag" aria-hidden="true"></i></span>
<%= f.collection_select :industry_id, Industry.order(:industry_name), :id, :industry_name, {prompt: "Select a Industry"}, {class: "form-control mb-5"} %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :start_date %></i></strong>
</div>
<div class="col-md-4">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-calendar" aria-hidden="true"></i></span>
<%= date_field("date", "start_date", class: 'form-control mb-5', value: session[:start_date]) %>
</div>
</div>
<div class="col-md-2 mb-5">
<strong><i class="text-danger"><%= f.label :end_date %></i></strong>
</div>
<div class="col-md-4">
<div class="input-group">
<span class="input-group-addon mb-5"><i class="fa fa-calendar" aria-hidden="true"></i></span>
<%= date_field("date", "end_date", class: 'form-control mb-5', value: session[:end_date]) %>
</div>
</div>
<!--end set field all -->
<div class="col-sm-2"></div>
<div class="col-sm-5">
<%= button_tag(name: "search", type: "submit", class: "btn btn-danger btn-block") do %>
<i class="fa fa-check 4px"></i> Search
<% end %>
</div>
<div class="col-sm-5">
<%= button_tag(name: "downloadcv" , type: "submit", value: "demo",class: "btn btn-danger btn-block") do %>
<i class="fa fa-check 4px"></i> Download CSV
<% end %>
</div>
</div>
<!--end set button -->
\ No newline at end of file
<div class="container mt-5" >
<div class="row mb-5 ml-5">
<div class="search_list titlejob col-md-10">
<%= link_to apply.job.job_title, job_detail_path(apply.job),class: 'search_list_jobs_title' %>
<li class="detail_description">
<%= apply.user.name %>
</li>
<div class="row ml-0">
<li class="detail_description col-md-10">
<%= apply.user.cv %>
</li>
<li class="detail_description col-md-5">
<%= apply.user.email %>
</li>
<li class=" detail_description float-right text-danger col-md-5">
<%= apply.updated_at %>
</li>
<li class="detail_description col-md-5">
Expiry Date: <%= apply.job.expiry_date %>
</li>
</div>
</div>
</div>
</div>
\ No newline at end of file
<%= provide(:title,"Admin Login")%>
<h1 class="text-center text-danger">Admin Login</h1>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(:session, url: login_admin_path) do |f| %>
<%= render "login_form", f: f %>
<% end %>
</div>
</div>
<%= provide(:title,"Applied Jobs") %>
<div class="text-primary text-center">
<h1 class="text-danger">Applied Jobs</h1>
</div>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(:session, url: search_applied_path) do |f| %>
<%= render "search_apply", f: f %>
<% end %>
</div>
</div>
<div class="mt-4">
<%= paginate @apply_job,theme: 'twitter-bootstrap-4'%>
<%= render partial: "list_applies",collection: @apply_job, as: :apply %>
<%= paginate @apply_job,theme: 'twitter-bootstrap-4'%>
</div>
\ No newline at end of file
<%= provide(:title,"Applied Jobs") %>
<div class="text-primary text-center">
<h1 class="text-danger">Applied Jobs</h1>
</div>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(:session, url: search_applied_path) do |f| %>
<%= render "search_apply", f: f %>
<% end %>
</div>
</div>
<h2 class="text-danger text-center mt-5">No result</h2>
\ No newline at end of file
<%= provide(:title,"Applied Jobs") %>
<div class="text-primary text-center">
<h1 class="text-danger">Applied Jobs</h1>
</div>
<div class="row ml-5 mt-5">
<div class="col-md-10 col-md-offset-3">
<%= form_for(:session, url: search_applied_path) do |f| %>
<%= render "search_apply", f: f %>
<% end %>
</div>
</div>
<div class="mt-4">
<%= render partial: "search_list",collection: @applies, as: :apply %>
</div>
<% if current_user.favorite?(job) %>
<%= render 'favorite/destroy', job_id: job['job_id'] %>
<% else %>
<%= render 'favorite/create', job_id: job['job_id'] %>
<% end %>
...@@ -23,10 +23,10 @@ ...@@ -23,10 +23,10 @@
<div class="col-md-2 mt-2"> <div class="col-md-2 mt-2">
<div id="follow_form_<%= job['job_id'].to_s %>"> <div id="follow_form_<%= job['job_id'].to_s %>">
<% if current_user.favorite?(job) %> <%if current_user.present? %>
<%= render 'favorite/destroy', job_id: job['job_id'] %> <%= render 'favorite_job', job: job %>
<% else %> <% else %>
<%= render 'favorite/create', job_id: job['job_id'] %> <%= link_to 'login please', login_user_path , class: 'text-danger'%>
<% end %> <% end %>
</div> </div>
</div> </div>
......
<div class="row"> <div class="row">
<div class="col"> <div class="col-md-4">
<a class="navbar-brand" href="<%= root_path %>"> <a class="navbar-brand" href="<%= root_path %>">
<%= image_tag("logo.png", class: "navbar-brand", id: "logo") %> <%= image_tag("logo.png", class: "navbar-brand", id: "logo") %>
</a> </a>
</div> </div>
<% if logged_admin? %>
<div class="col-md-4 mt-4 ">
<%= link_to logout_admin_path,class: 'btn btn-info btn-block mt-4 slide',method: :delete,data: { confirm: 'Are you sure?' } do %>
<i class="fa fa-sign-out"></i> Log Out
<% end %>
</div>
<% else %>
<div class="col-6 col-md-4"> <div class="col-6 col-md-4">
<ul class="nav navbar-nav" > <ul class="nav navbar-nav" >
<!-- Set up method log-out --> <!-- Set up method log-out -->
...@@ -73,5 +80,6 @@ ...@@ -73,5 +80,6 @@
<% end %> <% end %>
</ul> </ul>
</div> </div>
<% end %>
</div> </div>
<div class="col-4"> <div class="col-4">
<a href="#">
<p class="name_list_top"> <p class="name_list_top">
<%= city.location %> <%= link_to city.location ,search_city_path(:s => city.location) %>
</p> </p>
</a> </a>
<li class="total_jobs"> <li class="total_jobs">
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="col-md-4 list-group-item"> <div class="col-md-4 list-group-item">
<ul> <ul>
<li> <li>
<a href=""><%= city.location %></a> <%= link_to city.location,search_city_path(:s => city.location) %>
(<%= city.job_cities_count %>) (<%= city.job_cities_count %>)
</li> </li>
</ul> </ul>
</div> </div>
......
<div class="col-md-4 column_set"> <div class="col-md-4 column_set">
<a href="#" class="titlejob"> <a href="#" class="titlejob">
<p> <p>
<%= industry.industry_name %> <%= link_to industry.industry_name,search_industry_path(:s => industry.industry_name.delete("\"[/\]\"")) %>
</a> </a>
(<%= industry.job_industries_count %>) (<%= industry.job_industries_count %>)
</p> </p>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="col-md-4 list-group-item"> <div class="col-md-4 list-group-item">
<ul> <ul>
<li> <li>
<a href=""><%= industry.industry_name %></a> <%= link_to industry.industry_name, search_industry_path(:s => industry.industry_name.delete("\"[/\]\"")) %>
(<%= industry.job_industries_count %>) (<%= industry.job_industries_count %>)
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
your username is <br> your username is <br>
</p> </p>
<p> <p>
By clicking on the following link, you are confirming your email address and agreeing to VeNJOB's Terms of Service.: <%= @url %>. By clicking on the following link, you are confirming your email address and agreeing to VeNJOB's Terms of Service.:
<%= link_to "Confirm email", edit_user_url(activation_digest: @user.activation_digest,
email: @user.email,id: @user.id) %>
</p> </p>
<p>Thanks for joining and have a great day!</p> <p>Thanks for joining and have a great day!</p>
</body> </body>
......
require_relative 'boot' require_relative 'boot'
require 'rails/all' require 'rails/all'
require 'csv'
# Require the gems listed in Gemfile, including any gems # Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production. # you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups) Bundler.require(*Rails.groups)
......
...@@ -15,6 +15,8 @@ Rails.application.routes.draw do ...@@ -15,6 +15,8 @@ Rails.application.routes.draw do
root 'top_pages#top_page' root 'top_pages#top_page'
resources :job, except: :show resources :job, except: :show
get 'detail/:id', controller: :job, action: :detail, as: :job_detail get 'detail/:id', controller: :job, action: :detail, as: :job_detail
get 'job/:s',controller: :job,action: :index,as: :search_city
get 'job/:s',controller: :job,action: :index,as: :search_industry
get 'register/1',controller: :users,action: :new, as: :confirm_email get 'register/1',controller: :users,action: :new, as: :confirm_email
post 'register/2',controller: :users,action: :create, as: :create_email post 'register/2',controller: :users,action: :create, as: :create_email
...@@ -41,5 +43,12 @@ Rails.application.routes.draw do ...@@ -41,5 +43,12 @@ Rails.application.routes.draw do
get '/favorite_list',controller: :favorite,action: :favorite_list,as: :favorite_list get '/favorite_list',controller: :favorite,action: :favorite_list,as: :favorite_list
delete '/favorite_remove',controller: :favorite,action: :job_list_after_remove,as: :remove_job delete '/favorite_remove',controller: :favorite,action: :job_list_after_remove,as: :remove_job
get 'admin/login',controller: :admin,action: :admin,as: :login_form
post 'admin/login',controller: :admin,action: :login_admin,as: :login_admin
get 'admin/applies',controller: :admin,action: :applied_user_jobs,as: :applied_user
delete 'admin/applies',controller: :admin,action: :signout_admin,as: :logout_admin
post 'admin/applies',controller: :admin,action: :search_user_applied,as: :search_applied
# get 'admin/applies/download',controller: :admin,action: :download_csv,as: :download_csv
mount Sidekiq::Web => '/sidekiq' mount Sidekiq::Web => '/sidekiq'
end end
class CreateAdmins < ActiveRecord::Migration[5.1]
def change
create_table :admins do |t|
t.string :email
t.string :password
t.timestamps
end
end
end
class AddPasswordDigestToAdmins < ActiveRecord::Migration[5.1]
def change
add_column :admins, :password_digest, :string
end
end
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