Commit dbcda2ab by Hoang Phuc Do

Merge branch 'ID5_JObApply' into 'master'

create func apply job

See merge request !10
parents 378ba881 11225db1
Pipeline #958 failed with stages
in 0 seconds
......@@ -15,3 +15,8 @@
//= require turbolinks
//= require jquery.min
//= require_tree .
toastr.options = {
'closeButton': true,
'progressBar': true,
'timeOut': 10000
}
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
......@@ -34,5 +34,29 @@ $(document).on("turbolinks:load", function(){
console.log('bam')
body.stop().animate({ scrollTop: $('.title_list_city_qt').offset().top}, 700, 'swing');
});
// change lable
$("input[type=file]").on('change',function(){
document.getElementById ("label_name_file").innerHTML = this.files[0].name;
});
// show & hide password
$(".icon_show_password").on('click',function() {
$(".input_password").attr('type', 'text');
$(".icon_show_password").hide()
$(".icon_hide_password").show()
});
$(".icon_hide_password").on('click',function() {
$(".input_password").attr('type', 'password');
$(".icon_hide_password").hide()
$(".icon_show_password").show()
});
});
$(document).on("turbolinks:click", function(){
$(".box_loading").show();
});
$(document).on("turbolinks:load", function(){
$(".box_loading").hide();
});
// Place all the styles related to the apply_job controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the apply_job controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.box_job_apply {
font-family: 'Raleway', sans-serif;
padding: 20px;
border-radius: 4px;
width: 100%;
height: auto;
background-color: #fff;
box-shadow: 0px 0px 5px 1px rgba($color: #999, $alpha: 0.5);
margin-top: 30px;
}
.span_first {
color: rgb(221, 82, 82);
font-weight: 600;
}
.span_second {
color: #172642;
font-weight: 700;
}
.ribbon_item {
position: relative;
text-align: center;
height: 40px;
line-height: 40px;
font-size: 18px;
color: #666;
z-index: 100;
margin-bottom: 5px;
}
.ribbon_item.active {
background-color: #3d82be;
color: #fff;
&::before {
content: '';
z-index: 101;
position: absolute;
right: 0;
box-sizing: border-box;
width: 40px;
height: 40px;
border-top: 20px solid white;
border-bottom: 20px solid white;
border-left: 25px solid #3d82be;
}
&::after {
content: '';
z-index: 101;
position: absolute;
left: 0;
box-sizing: border-box;
width: 40px;
height: 40px;
border-top: 20px solid #3d82be;
border-bottom: 20px solid #3d82be;
border-left: 25px solid #fff;
}
}
.custom_badges {
font-size: 20px !important;
background-color: #000;
color: #fff;
font-weight: 600;
padding: 0px 8px 2px;
border-radius: 20%;
}
.custom_badges.active {
background-color: white;
color: #666;
padding: 0px 8px !important;
}
@media only screen and (max-width: 992px) {
}
\ No newline at end of file
......@@ -76,7 +76,6 @@ $main-color: #23303D;
}
.list_item_menu_header_right {
margin: 0 10px;
&:first-child {
margin-right: 4px;
position: relative;
......@@ -697,6 +696,9 @@ $main-color: #23303D;
transform: scale(1.002);
}
}
.box_jobs.applied {
height: auto !important;
}
.box_info {
position: relative;
......@@ -1149,6 +1151,16 @@ $main-color: #23303D;
background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
}
}
.btn-apply_job.inactive {
background-color: #283969;
font-weight: bold;
background-image: none;
color: white;
&:hover {
cursor: not-allowed;
}
}
.btn-apply_job_favorite {
margin-top: 20px;
width: 100%;
......@@ -1419,6 +1431,14 @@ $main-color: #23303D;
.pppp {
width: 100% !important;
}
.pppp.hidden {
display: none;
}
.lable_custom {
cursor: pointer;
font-size: 20px;
color: green;
}
.list_email_app {
ul {
......@@ -1538,3 +1558,55 @@ $main-color: #23303D;
#edit_user {
margin: auto;
}
.list_item_menu_header_right.have_menu {
position: relative;
&:hover .menu_hover {
display: block;
transition: 0.5s linear;
}
}
.menu_hover {
position: absolute;
z-index: 9000000;
top: 100%;
display: none;
left: -100%;
width: 150px;
height: auto;
background-color: #fff;
border-radius: 4px;
box-shadow: 1px -1px 5px 2px rgba($color: #000000, $alpha: 0.2);
transition: 0.5s linear;
&::before {
cursor: pointer;
content: '';
position: absolute;
width: 150px;
height: 28px;
background-color: transparent;
top: -22px;
left: 0;
}
&::after {
content: '';
position: absolute;
width: 28px;
height: 28px;
border-top: 14px solid transparent;
border-left: 14px solid transparent;
border-right: 14px solid transparent;
border-bottom: 14px solid #fff;
top: -35%;
left: 50%;
}
ul {
list-style: none;
padding: 10px 15px;
li {
&:last-child {
margin-top: 5px;
}
}
}
}
\ No newline at end of file
// Place all the styles related to the users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.input_password {
position: relative;
}
@mixin icon_password {
font-size: 14px;
position: absolute;
right: 4%;
top: 50%;
transform: translateY(-50%);
&:hover {
cursor: pointer;
}
}
.icon_show_password {
@include icon_password;
display: block;
}
.icon_hide_password {
@include icon_password;
display: none;
}
@media only screen and (max-width: 992px) {
.icon_show_password {
right: 6%;
}
.icon_hide_password {
right: 6%;
}
}
\ No newline at end of file
......@@ -8,12 +8,12 @@ class ApplicationController < ActionController::Base
before_action :set_locale
def set_locale
locale = params[:locale].to_s.strip.to_sym
locale = (user_signed_in? ? current_user.language : params[:locale].to_s.strip).to_sym
I18n.locale = I18n.available_locales.include?(locale) ? locale : I18n.default_locale
end
def default_url_options
{locale: I18n.locale}
{ locale: I18n.locale }
end
protected
......
# frozen_string_literal: true
# Applied jobs controller
class ApplyJobController < ApplicationController
before_action :authenticate_user!
def index
@jobs = current_user.applied_jobs.includes(:job).order(created_at: :desc).page(params[:page]).per(6)
end
def apply
return redirect_to root_path if params[:job_id].blank?
@data_apply = current_user.applied_jobs.new(name: current_user.name, email: current_user.email)
session[:job_id] = params[:job_id]
@job = Job.find(params[:job_id])
end
def confirm
@apply_job = current_user.applied_jobs.new(applied_job_params)
@apply_job.job_id = session[:job_id]
@apply_job.cv = current_user.cv if @apply_job.cv.blank?
session[:cache_name] = @apply_job.cv.cache_name
if @apply_job.invalid?
helpers.render_errors(@apply_job)
redirect_to apply_path(job_id: session[:job_id])
end
end
def done
apply_data = current_user.applied_jobs.new(applied_job_params)
apply_data.job_id = session[:job_id]
apply_data.cv.retrieve_from_cache!(session[:cache_name])
if apply_data.save
AppliedMailer.applied_job_mail_to(apply_data).deliver_now
render :done
else
flash[:error] = t('apply_job.error')
redirect_to apply_path(job_id: applied_job_params[:job_id])
end
session.delete(:job_id)
session.delete(:cache_name)
end
private
def applied_job_params
params.require(:applied_job).permit(:name, :email, :cv)
end
end
......@@ -7,6 +7,10 @@ class UsersController < ApplicationController
render :confirm
end
def my_page
def my_page; end
def set_lang
current_user.update_current_language(params[:lang]) if user_signed_in?
redirect_to '/'
end
end
# frozen_string_literal: true
class AppliedJobDecorator < Draper::Decorator
delegate_all
def applied_at
object.created_at.localtime.strftime('%H:%M %d - %m - %Y')
end
end
class RegistrationDecorator < Draper::Decorator
delegate_all
# Define presentation-specific methods here. Helpers are accessed through
# `helpers` (aka `h`). You can override attributes, for example:
#
# def created_at
# helpers.content_tag :span, class: 'time' do
# object.created_at.strftime("%a %m/%d/%y")
# end
# end
end
class UserDecorator < Draper::Decorator
delegate_all
# Define presentation-specific methods here. Helpers are accessed through
# `helpers` (aka `h`). You can override attributes, for example:
#
# def created_at
# helpers.content_tag :span, class: 'time' do
# object.created_at.strftime("%a %m/%d/%y")
# end
# end
end
......@@ -10,6 +10,7 @@ module ApplicationHelper
def custom_bootstrap_flash
flash_messages = []
flash.each do |type, message|
next if message.blank?
type = 'success' if type == 'notice'
type = 'error' if type == 'alert'
text = "<script>toastr.#{type}('#{message}');</script>"
......
# frozen_string_literal: true
module ApplyJobHelper
def render_errors(obj)
errors = []
obj.errors.full_messages.each { |mess| errors << "#{mess}<br>" }
flash[:error] = errors.join('<br>').html_safe
end
end
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
default from: ENV['SENDMAIL_USERNAME']
layout 'mailer'
end
class AppliedMailer < ApplicationMailer
def applied_job_mail_to(obj)
@applied_job = obj
emails = [@applied_job.email, ENV['SENDMAIL_USERNAME']]
mail(to: emails, subject: t('apply_job.subject'))
end
end
......@@ -2,6 +2,11 @@
# Description/Explanation of Person class
class AppliedJob < ApplicationRecord
mount_uploader :cv, CvUploader
belongs_to :user
belongs_to :job
validates :name, :email, :cv, presence: true
validates :name, :email, length: { in: 4..200 }
validates :email, format: Devise.email_regexp
validates_uniqueness_of :user_id, scope: :job_id, message: I18n.t('apply_job.already_taken')
end
......@@ -4,6 +4,7 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
VALID_LANG_CODES = %w[vi en].freeze
mount_uploader :cv, CvUploader
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
......@@ -12,6 +13,13 @@ class User < ApplicationRecord
has_many :histories
has_many :favorites
validates_length_of :name, within: 8..200
validates_length_of :name, within: 4..200
validates_length_of :email, within: 8..200
def update_current_language(new_lang)
return if new_lang == language || VALID_LANG_CODES.exclude?(new_lang)
self.language = new_lang
save
end
end
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Thank you for applied with VenJOB</title>
</head>
<body>
<div class="container">
<span style="font-size: 18px;"><b>Dear <%= @applied_job.name %></b></span>
<div style="font-size: 15px;">
<p>Thank you for applied with VenJOB. Your applied job's information is as follow:</p>
<span>Job title: <%= @applied_job.job.name %></span><br>
<span>Location: <%= @applied_job.job.cities.map(&:name).join(' ') %></span><br>
<span>Company: <%= @applied_job.job.company.name %></span><br><br>
<span>Name: <%= @applied_job.name %></span><br>
<span>Email: <%= @applied_job.email %></span><br>
CV: <%= link_to @applied_job.cv.identifier, root_url(@applied_job.cv.url), target: '_blank' %>
<p>Best</p>
</div>
</div>
</body>
</html>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="box_jobs applied">
<div class="row">
<div class="col-lg-12">
<div class="box_info">
<div class="lol">
<%= link_to data.job.name, detail_job_path(id: data.job.id), class: 'job_name' %>
</div>
<div class="coc">
<h5 class="box_info_des"><%= strip_tags(data.job.description) %></h5>
</div>
<div style="margin-top: 8px;">
<div class="row">
<div class="col-lg-4">
<div class="loc">
<h5 class="box_info_location"><i class="fas fa-map-marker-alt"></i>
<%= data.job.cities.map(&:name).join(' | ') %>
</h5>
</div>
</div>
<div class="col-lg-3">
<h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp;<%= "#{t('pages.index.salary')}: #{data.job.salary}" %></h5>
</div>
<div class="col-lg-5">
<h5 class="box_info_salary"><%= "#{t('pages.index.applied_at')}: #{data.decorate.applied_at}" %></h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<%= form_with(model: data_apply, url: confirm_path, html: { multipart: true }, local: true) do |f| %>
<br>
<div class="container">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<%= f.label :name, t('pages.mypage.name') %>
</div>
<div class="col-lg-6">
<%= f.text_field(:name, autofocus: true, autocomplete: 'name', class:'form-control') %>
</div>
</div><br>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<%= f.label :email%>
</div>
<div class="col-lg-6">
<%= f.text_field(:email, autofocus: true, autocomplete: 'email', class:'form-control') %>
</div>
</div><br>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<span><%= t('pages.mypage.cv') %></span>
</div>
<div class="col-lg-5 col-md-12">
<%= f.label :cv, current_user.cv.identifier ? current_user.cv.identifier : t('pages.mypage.nofile'), id: 'label_name_file' %>
<%= f.file_field :cv, accept: '.pdf, .zip', class: 'pppp hidden' %>
</div>
<div class="col-lg-1">
<%= f.label :cv, '<i class="fas fa-cloud-upload-alt"></i>'.html_safe, title: 'upload', class: 'lable_custom' %>
</div>
</div><br>
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-4">
<%= f.submit t('pages.apply.btn_text_confirm'), class:'btn btn-success btn-info-custom' %>
</div>
</div>
</div>
<% end %>
<hr>
<div class="ribbon">
<div class="row">
<div class="col-lg-4 col-md-12">
<div class="ribbon_item <%= attr_active_1 %>">
<span class="custom_badges <%= attr_active_1 %>">1</span> <%= t('pages.apply.ribon_1') %>
</div>
</div>
<div class="col-lg-4 col-md-12">
<div class="ribbon_item <%= attr_active_2 %>">
<span class="custom_badges <%= attr_active_2 %>">2</span> <%= t('pages.apply.ribon_2') %>
</div>
</div>
<div class="col-lg-4 col-md-12">
<div class="ribbon_item <%= attr_active_3 %>">
<span class="custom_badges <%= attr_active_3 %>">3</span> <%= t('pages.apply.ribon_3') %>
</div>
</div>
</div>
<hr>
</div>
<div class="container">
<div class="box_job_apply">
<%= render 'ribbon', attr_active_1: 'active', attr_active_2: '', attr_active_3: '' %>
<div class="form_apply_job">
<span style="font-size:20px"> <%= t('apply_job.job')%>: </span><span style="font-size: 26px; color: red; font-weight:bold;"><%= @job.name %></span><br><br>
<span class="span_second"><%= t('pages.apply.title_input_1') %></span><br>
<span><%= t('pages.apply.title_input_2') %></span>
<%= render 'form', data_apply: @data_apply %>
</div>
</div>
</div>
<div style="width: 100%; height: 25vh"></div>
<div class="container">
<div class="box_job_apply">
<%= render 'ribbon', attr_active_1: 'active', attr_active_2: 'active', attr_active_3: '' %>
<div class="form_apply_job">
<span class="span_second"><%= t('apply_job.confirm') %></span>
<br><br>
<div class="container">
<%= form_with(model: @apply_job, url: done_path, local: true) do |f| %>
<br>
<div class="container">
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<%= f.label :name, t('pages.mypage.name') %>
</div>
<div class="col-lg-6">
<%= @apply_job.name %>
<%= f.hidden_field(:job_id, value: @apply_job.job_id) %>
<%= f.hidden_field(:name, value: @apply_job.name) %>
</div>
</div><br>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<%= f.label :email%>
</div>
<div class="col-lg-6">
<%= @apply_job.email %>
<%= f.hidden_field(:email, value: @apply_job.email) %>
</div>
</div><br>
<div class="row">
<div class="col-lg-2"></div>
<div class="col-lg-2">
<span><%= t('pages.mypage.cv') %></span>
</div>
<div class="col-lg-5 col-md-12">
<%= f.file_field :cv, accept: '.pdf, .zip', class: 'pppp hidden' %>
<%= @apply_job.cv.identifier %>
</div>
</div><br>
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-4">
<%= f.submit t('pages.apply.btn_text_confirm'), class:'btn btn-success btn-info-custom' %>
</div>
</div>
</div>
<% end %>
<hr>
</div>
<%= link_to t('devise.back'), :back %>
</div>
</div>
</div>
<% provide(:title, "#{t('apply_job.done')}") %>
<div class="container">
<div class="box_job_apply">
<%= render 'ribbon', attr_active_1: 'active', attr_active_2: 'active', attr_active_3: 'active' %>
<span style="font-size: 22px;"><%= t('apply_job.thanks') %></span><hr>
<%= link_to t('apply_job.backtotop'), root_path, class: 'link_ct' %>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<hr>
<div class="box_text_five_jobs">
<span><%= t('apply_job.title') %></span>
</div>
<hr>
</div>
<% if @jobs.blank? %>
<div class="col-lg-12">
<div class="breadcrumb_total_search">
<span class="breadcrumb-item active">
<%= t('apply_job.no_record') %>
</span>
</div>
</div>
<% else %>
<%= render partial: 'apply_job/block_info_job', collection: @jobs, as: :data %>
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div id="paginator">
<%= paginate @jobs %>
</div>
</div>
</div>
</div>
<% end %>
</div>
</div>
......@@ -34,7 +34,7 @@
<%= f.label :cv, t('pages.mypage.cv') %>
</div>
<div class="col-md-9">
<%= f.file_field :cv, autofocus: true, class: 'pppp' %>
<%= f.file_field :cv, accept: '.pdf', autofocus: true, class: 'pppp' %>
<i style="font-size: 15px; color: #666">Current file: <%= current_user.cv.identifier %></i>
</div>
</div><br>
......
......@@ -31,7 +31,7 @@
<%= f.label :cv, t('pages.mypage.cv') %>
</div>
<div class="col-md-9">
<%= f.file_field :cv, autofocus: true, class: 'pppp' %>
<%= f.file_field :cv, accept: '.pdf', autofocus: true, class: 'pppp' %>
</div>
</div><br>
<div class="row">
......
......@@ -25,7 +25,9 @@
<%= f.label :password, t('devise.pass_word') %>
</div>
<div class="col-md-9">
<%= f.password_field :password, autocomplete: 'new-password', class: 'form-control' %>
<%= f.password_field :password, autocomplete: 'new-password', class: 'form-control input_password' %>
<span class="icon_show_password"><i class="far fa-eye"></i></span>
<span class="icon_hide_password"><i class="far fa-eye-slash"></i></span>
</div>
</div><br>
<div class="row">
......
......@@ -24,7 +24,13 @@
</div>
<div class="col-lg-3">
<div class="btn_apply_job">
<%= link_to t('pages.detail.btr_text_submit_cv'), '#', class: 'btn btn-apply_job' %>
<% if user_signed_in? %>
<%= link_to_if(current_user.applied_jobs.find_by(job_id: @job.id).present?, t('apply_job.applied'), '#', class: 'btn btn-apply_job inactive') do
link_to t('pages.detail.btr_text_submit_cv'), apply_path(job_id: @job.id), class: 'btn btn-apply_job'
end %>
<% else %>
<%= link_to t('pages.detail.btr_text_submit_cv'), apply_path(job_id: @job.id), class: 'btn btn-apply_job' %>
<% end %>
</div>
</div>
<div class="col-lg-12 col-md-12">
......@@ -32,7 +38,7 @@
<div class="box_detail_jobs_location">
<span><i class="fas fa-map-marker-alt"></i><%= t('pages.detail.work_location') %></span>
<% @job.cities.each do |x| %>
<%= link_to "&nbsp;#{x.name}&nbsp;".html_safe , jobs_path(model: 'city', slug: x.slug), class: 'link_ct apply_job link_optimize'%>
<%= link_to "&nbsp;#{x.name}&nbsp;".html_safe, jobs_path(model: 'city', slug: x.slug), class: 'link_ct apply_job link_optimize'%>
<% end %>
</div>
<div class="box_detail_jobs_salary">
......@@ -80,7 +86,13 @@
<div class="row">
<div class="col-lg-6 col-md-6">
<div class="btn_apply_job">
<%= link_to t('pages.detail.btr_text_submit_cv'), '#', class: 'btn btn-apply_job' %>
<% if user_signed_in? %>
<%= link_to_if(current_user.applied_jobs.find_by(job_id: @job.id), t('apply_job.applied'), '#', class: 'btn btn-apply_job inactive') do
link_to t('pages.detail.btr_text_submit_cv'), apply_path(job_id: @job.id), class: 'btn btn-apply_job'
end %>
<% else %>
<%= link_to t('pages.detail.btr_text_submit_cv'), apply_path(job_id: @job.id), class: 'btn btn-apply_job' %>
<% end %>
</div>
</div>
<div class="col-lg-6 col-md-6">
......
<li class='page-item disabled'>
<%= link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link' %>
<%= link_to raw('...'), '#', class: 'page-link' %>
</li>
......@@ -25,10 +25,24 @@
link_to t('pages.index.register'), new_user_registration_path, class: 'link_item_menu_header_right'
end %>
</li>
<li class="list_item_menu_header_right">
<span class="link_item_menu_header_right custom"><%= t('pages.index.language') %></span>&nbsp;
<%= link_to image_tag('flagvn.png', class: 'header_img_flag'), locale:'vi' %><span style="color: #999;"> | </span>
<%= link_to image_tag('flagusa.png', class: 'header_img_flag'), locale:'en' %>
<li class="list_item_menu_header_right have_menu">
<%= link_to t('pages.index.language'), '#', class: 'link_item_menu_header_right' %>
<div class="menu_hover">
<ul>
<li>
<%= image_tag('flagusa.png', class: 'header_img_flag')%>
<%= link_to_if(user_signed_in?, t('pages.index.en'), set_lang_path(lang: 'en'), class: 'link_ct apply_job') do
link_to t('pages.index.en'), {locale: 'en'}, {class: 'link_ct apply_job'}
end %>
</li>
<li>
<%= image_tag('flagvn.png', class: 'header_img_flag')%>
<%= link_to_if(user_signed_in?, t('pages.index.vi'), set_lang_path(lang: 'vi'), class: 'link_ct apply_job') do
link_to t('pages.index.vi'), {locale: 'vi'}, {class: 'link_ct apply_job'}
end %>
</li>
</ul>
</div>
</li>
</ul>
</div>
......@@ -58,8 +72,13 @@
<span class="link_item_menu_mobile custom"><%= t('pages.index.language') %></span>
</li>
<li class="item_menu_mobile_vertical">
<%= link_to 'Vietnamese', locale:'vi', class: 'link_item_menu_mobile' %><span style="color: #999;"> |</span>
<%= link_to 'English', locale:'en', class: 'link_item_menu_mobile' %>
<%= link_to_if(user_signed_in?, t('pages.index.en'), set_lang_path(lang: 'en'), class: 'link_item_menu_mobile') do
link_to t('pages.index.en'), {locale: 'en'}, {class: 'link_item_menu_mobile'}
end %>
<span style="color: #999;"> |</span>
<%= link_to_if(user_signed_in?, t('pages.index.vi'), set_lang_path(lang: 'vi'), class: 'link_item_menu_mobile') do
link_to t('pages.index.vi'), {locale: 'vi'}, {class: 'link_item_menu_mobile'}
end %>
</li>
</ul>
</div>
......
......@@ -19,6 +19,7 @@
<%= render 'layouts/padding' %>
<%= yield %>
<%= render 'layouts/footer' %>
<%= render 'shared/loading' %>
</div>
</body>
</html>
<% if resource.errors.any? %>
<div id="error_explanation">
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
\ No newline at end of file
<style>
body {
padding: 0;
margin: 0;
}
.box_loading {
z-index: 9999999;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
box-sizing: border-box;
background-image:
linear-gradient(to bottom, rgba(112, 112, 112, 0.486), rgba(112, 112, 112, 0.486));
}
.content {
position: absolute;
top: 50%;
left: 50%;
width: 60px;
height: 60px;
border-radius: 50%;
border: 4px solid #f3f3f3c0;
border-left: 4px solid rgb(219, 37, 13);
border-right: 4px solid rgb(219, 37, 13);
transform: translateX(-50%) translateY(-50%);
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<div class="box_loading">
<div class="content"></div>
</div>
......@@ -26,7 +26,7 @@
<hr>
<div class="col-lg-6">
<%= link_to t('pages.mypage.update'), edit_user_registration_path, class: 'btn btn-info btn-custom-padding'%>
<%= link_to t('pages.mypage.myjob'), '#', class: 'btn btn-warning btn-custom-padding'%>
<%= link_to t('pages.mypage.myjob'), list_applied_jobs_path, class: 'btn btn-warning btn-custom-padding'%>
</div>
</div>
<hr>
......
......@@ -22,7 +22,7 @@ Rails.application.configure do
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = false
config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
......
......@@ -24,6 +24,10 @@ en:
more: 'More'
btn_text_favorite: 'Favorite'
salary: ' Salary'
vi: 'Vietnamese'
en: 'English'
setting: 'Settings'
applied_at: 'Applied_at'
banner:
slogan: 'VENJOB HUMAN RESOURCE PLATFORM'
slogan_2: 'Instantly discover the best jobs on VenJob'
......@@ -50,6 +54,13 @@ en:
domestic: 'Viet Nam'
international: 'International'
provinces_vn: 'Provinces and cities of Vietnam'
apply:
ribon_1: 'Enter your information'
ribon_2: 'Confirmation'
ribon_3: 'Done'
title_input_1: 'Fill in your contact information and choose a profile to apply for:'
title_input_2: 'Your contact information:'
btn_text_confirm: 'Confirm'
mypage:
title: 'My page'
email: 'Email'
......@@ -108,3 +119,20 @@ en:
cancel_my_acc: 'Cancel my account'
remember_me: 'Remember Me'
ask_forget_password: 'Forgot your password?'
apply_job:
success: 'Successful manipulation'
error: 'Manipulation failed. Please try again'
thanks: 'Thanks you for apply!'
backtotop: 'Back to homepage'
done: 'Done'
subject: 'Thank you for apply with VeNJOB'
job: 'Job'
confirm: 'Please confirm your information'
applied: 'Applied'
title: 'List Applied Jobs'
no_record: "You haven't applied yet."
already_taken: 'We have received your resume, the employer will contact you as soon as possible.'
activerecord:
attributes:
applied_job:
user_id: ''
......@@ -24,6 +24,10 @@ vi:
more: 'Xem thêm'
btn_text_favorite: 'Yêu thích'
salary: ' Lương'
vi: 'Tiếng Việt'
en: 'Tiếng Anh'
setting: 'Cài đặt'
applied_at: 'Ứng tuyển lúc: '
banner:
slogan: 'NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB'
slogan_2: 'Khám phá ngay những việc làm tốt nhất trên VenJob'
......@@ -50,6 +54,13 @@ vi:
domestic: 'Việt Nam'
international: 'Nước ngoài'
provinces_vn: 'Các tỉnh, thành phố thuôc Việt Nam'
apply:
ribon_1: 'Nhập thông tin'
ribon_2: 'Xác nhận thông tin'
ribon_3: 'Hoàn thành'
title_input_1: 'Điền thông tin liên hệ của bạn chọn hồ để ứng tuyển:'
title_input_2: 'Thông tin liên hệ của bạn:'
btn_text_confirm: 'Xác nhận'
mypage:
title: 'Trang nhân'
email: 'Email'
......@@ -108,4 +119,21 @@ vi:
cancel_my_acc: 'Xóa tài khoản'
remember_me: 'Nhớ mật khẩu'
ask_forget_password: 'Bạn quên mật khẩu?'
apply_job:
success: 'Thao tác thành công'
error: 'Thao tác không thành công. Vui lòng thử lại'
thanks: 'Cảm ơn bạn đã đồng hành cùng chúng tôi'
backtotop: 'Quay lại trang chủ'
done: 'Hoàn thành'
subject: 'Cảm ơn bạn đã đăng với VeNJOB'
job: 'Công Việc'
confirm: 'Vui lòng xác nhận lại thông tin của bạn'
applied: 'Đã ứng tuyển'
title: 'Danh sách công việc đã ứng tuyển'
no_record: 'Bạn chưa ứng tuyển công việc nào hết.'
already_taken: 'Chúng tôi đã tiếp nhận hồ của bạn, nhà tuyển dụng sẽ liên hệ đến bạn trong thời gian sớm nhất.'
activerecord:
attributes:
applied_job:
user_id: ''
\ No newline at end of file
# frozen_string_literal: true
Rails.application.routes.draw do
get 'setting', to: 'users#set_lang', as: :set_lang
scope '(:locale)', locale: /en|vi/ do
devise_for :users, controllers: {registrations: 'registrations'}
devise_for :users, controllers: { registrations: 'registrations' }
root 'home#index'
get 'register/:code', to: 'users#confirm_sign_up', as: :confirm_sign_up
get 'industries', to: 'industry#index', as: :industry_index
get 'cities', to: 'city#index', as: :city_index
# Applied job
get 'apply', to: 'apply_job#apply', as: :apply
post 'confirm', to: 'apply_job#confirm', as: :confirm
post 'done', to: 'apply_job#done', as: :done
get 'my/jobs', to: 'apply_job#index', as: :list_applied_jobs
# Details job
get 'detail/:id', to: 'job#detail', as: :detail_job
# Search
......
class AddColumnLanguageToTableUsers < ActiveRecord::Migration[5.2]
def change
add_column :users, :language, :string, default: 'vi'
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_08_11_005812) do
ActiveRecord::Schema.define(version: 2020_08_17_004611) do
create_table "applied_jobs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
t.bigint "user_id"
......@@ -108,6 +108,7 @@ ActiveRecord::Schema.define(version: 2020_08_11_005812) do
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.string "language", default: "vi"
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
......
require 'test_helper'
class AppliedMailerTest < ActionMailer::TestCase
# test "the truth" do
# assert true
# end
end
# Preview all emails at http://localhost:3000/rails/mailers/applied_mailer
class AppliedMailerPreview < ActionMailer::Preview
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