Commit f67931d4 by Hung0326 Committed by GitHub

Merge pull request #13 from Hung0326/id5

Id5
parents a93ab3c6 3e064621
...@@ -13,7 +13,7 @@ gem 'sass-rails', '~> 5.0' ...@@ -13,7 +13,7 @@ gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0' gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes # See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby # gem 'mini_racer', platforms: :ruby
gem "breadcrumbs_on_rails"
# Use CoffeeScript for .coffee assets and views # Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2' gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
...@@ -23,6 +23,9 @@ gem 'jbuilder', '~> 2.5' ...@@ -23,6 +23,9 @@ gem 'jbuilder', '~> 2.5'
gem 'nokogiri' gem 'nokogiri'
gem 'rubyzip' gem 'rubyzip'
gem 'whenever' gem 'whenever'
gem 'kaminari'
gem 'jquery-rails'
gem 'rails-asset-jqueryui'
# Use Redis adapter to run Action Cable in production # Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0' # gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password # Use ActiveModel has_secure_password
......
...@@ -51,6 +51,8 @@ GEM ...@@ -51,6 +51,8 @@ GEM
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.4.6) bootsnap (1.4.6)
msgpack (~> 1.0) msgpack (~> 1.0)
breadcrumbs_on_rails (4.0.0)
rails (>= 5.0)
builder (3.2.4) builder (3.2.4)
byebug (11.1.3) byebug (11.1.3)
capybara (3.33.0) capybara (3.33.0)
...@@ -86,6 +88,22 @@ GEM ...@@ -86,6 +88,22 @@ GEM
io-like (0.3.1) io-like (0.3.1)
jbuilder (2.10.0) jbuilder (2.10.0)
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
jquery-rails (4.4.0)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
kaminari (1.2.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.1)
kaminari-activerecord (= 1.2.1)
kaminari-core (= 1.2.1)
kaminari-actionview (1.2.1)
actionview
kaminari-core (= 1.2.1)
kaminari-activerecord (1.2.1)
activerecord
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
libv8 (3.16.14.19) libv8 (3.16.14.19)
listen (3.1.5) listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
...@@ -133,6 +151,8 @@ GEM ...@@ -133,6 +151,8 @@ GEM
bundler (>= 1.3.0) bundler (>= 1.3.0)
railties (= 5.2.4.3) railties (= 5.2.4.3)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-asset-jqueryui (0.0.3)
jquery-rails
rails-dom-testing (2.0.3) rails-dom-testing (2.0.3)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
nokogiri (>= 1.6) nokogiri (>= 1.6)
...@@ -228,11 +248,14 @@ PLATFORMS ...@@ -228,11 +248,14 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bootsnap (>= 1.1.0) bootsnap (>= 1.1.0)
breadcrumbs_on_rails
byebug byebug
capybara (>= 2.15) capybara (>= 2.15)
chromedriver-helper chromedriver-helper
coffee-rails (~> 4.2) coffee-rails (~> 4.2)
jbuilder (~> 2.5) jbuilder (~> 2.5)
jquery-rails
kaminari
listen (>= 3.0.5, < 3.2) listen (>= 3.0.5, < 3.2)
mysql2 (= 0.5.3) mysql2 (= 0.5.3)
nokogiri nokogiri
...@@ -240,6 +263,7 @@ DEPENDENCIES ...@@ -240,6 +263,7 @@ DEPENDENCIES
pry pry
puma (~> 3.11) puma (~> 3.11)
rails (~> 5.2.4, >= 5.2.4.3) rails (~> 5.2.4, >= 5.2.4.3)
rails-asset-jqueryui
rails_12factor rails_12factor
rubocop rubocop
rubyzip rubyzip
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives. // about supported directives.
// //
//= require jquery
//= require rails-ujs //= require rails-ujs
//= require activestorage //= require activestorage
//= require turbolinks //= require turbolinks
......
# 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/
# 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/
$(document).on("turbolinks:load", function(){ $(document).on("turbolinks:load", function(){
$('.btn_favorite_outline').click(function (e) {
$(this).toggleClass('active'); $('.block_click_favorite').click(function (e) {
$('.overlay_login').addClass('show');
}); });
$('.icon_close_modal_login').click(function (e) {
$('.overlay_login').removeClass('show');
});
// => scroll to top
$(window).scroll(function(){
if ($(this).scrollTop() > 550) {
$(".btn-scroll-top").css('opacity',1);
$(".btn-scroll-top").fadeIn(400);
} else {
$(".btn-scroll-top").fadeOut(400);
}
});
$(".btn-scroll-top").click(function (e){
var body = $("html, body");
body.stop().animate({ scrollTop: 0}, 700, 'swing')
});
// => end
$(".btn_option_location-vn").click(function (){
var body = $("html, body");
$('.btn_option_location-vn').addClass('active');
body.stop().animate({ scrollTop: $('.title_list_city_vn').offset().top}, 700, 'swing');
});
$(".btn_option_location-qt").click(function (){
var body = $("html, body");
console.log('bam')
body.stop().animate({ scrollTop: $('.title_list_city_qt').offset().top}, 700, 'swing');
});
}); });
# 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/
# 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/
# 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/
// 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 city controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
...@@ -7,6 +7,43 @@ body { ...@@ -7,6 +7,43 @@ body {
overflow: hidden; overflow: hidden;
// background-color: #f0f0f0; // background-color: #f0f0f0;
} }
.pre_desc {
white-space: pre-wrap;
text-overflow: clip;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 16px;
}
// scroll to top
.btn-scroll-top {
position: fixed;
bottom: 30px;
right: 30px;
height: 50px;
width: 50px;
border-radius: 5px;
background-color: rgba($color: #000000, $alpha: 0.2);
cursor: pointer;
padding: 12px;
z-index: 2000;
transition: 0.3;
opacity: 0;
&:hover {
background-color: rgba($color: #000000, $alpha: 0.7);
transition: 0.3;
.icon-scroll {
color: #fff !important;
}
}
}
.box-btn-scroll-top {
height: 30px;
transform: translateY(-5px);
.icon-scroll {
font-size: 40px;
color: rgba($color: #636363, $alpha: 0.8);
}
}
$breakpoint-tablet: 992px; $breakpoint-tablet: 992px;
$main-color: #23303D; $main-color: #23303D;
...@@ -14,7 +51,7 @@ $main-color: #23303D; ...@@ -14,7 +51,7 @@ $main-color: #23303D;
.cus_header { .cus_header {
height: 52px; height: 52px;
width: 100%; width: 100%;
background-color: $main-color; background-image: linear-gradient(20deg, #434343, #000000);
position: fixed; position: fixed;
border-bottom: 1px solid #333; border-bottom: 1px solid #333;
// box-shadow: 0px 2px 4px 2px #999; // box-shadow: 0px 2px 4px 2px #999;
...@@ -199,14 +236,20 @@ $main-color: #23303D; ...@@ -199,14 +236,20 @@ $main-color: #23303D;
.menu__mobile { .menu__mobile {
width: 65vw; width: 65vw;
} }
.breadcrumb_total_search {
span {
font-size: 14px;
}
}
} }
// end header // end header
// footer // footer
.custom_footer { .custom_footer {
margin-top: 30px;
width: 100%; width: 100%;
height: 120px; height: 120px;
background-color: $main-color; background-color: black;
position: relative; position: relative;
} }
.copyright { .copyright {
...@@ -239,7 +282,7 @@ $main-color: #23303D; ...@@ -239,7 +282,7 @@ $main-color: #23303D;
.slogan_text { .slogan_text {
text-align: center; text-align: center;
font-family: 'Raleway', sans-serif; font-family: 'Raleway', sans-serif;
font-size: 35px; font-size: 40px;
color: #eaeaea; color: #eaeaea;
transform: scale(1.35); transform: scale(1.35);
font-weight: 700; font-weight: 700;
...@@ -610,7 +653,7 @@ $main-color: #23303D; ...@@ -610,7 +653,7 @@ $main-color: #23303D;
span { span {
font-family: 'Raleway', sans-serif; font-family: 'Raleway', sans-serif;
font-size: 30px; font-size: 30px;
font-weight: 200; font-weight: 400;
} }
} }
...@@ -624,7 +667,6 @@ $main-color: #23303D; ...@@ -624,7 +667,6 @@ $main-color: #23303D;
margin-top: 10px; margin-top: 10px;
margin-bottom: 5px; margin-bottom: 5px;
border-radius: 2px; border-radius: 2px;
// border-top: 1px solid rgba($color: #000000, $alpha: 0.2); // border-top: 1px solid rgba($color: #000000, $alpha: 0.2);
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2); border-bottom: 1px solid rgba($color: #000000, $alpha: 0.2);
transition: 0.2s; transition: 0.2s;
...@@ -638,8 +680,8 @@ $main-color: #23303D; ...@@ -638,8 +680,8 @@ $main-color: #23303D;
.box_info { .box_info {
position: relative; position: relative;
margin: 10px 0px 10px 25px; margin: 10px 0px 10px 25px;
} }
.img_job_name { .img_job_name {
width: 18px; width: 18px;
height: 18px; height: 18px;
...@@ -693,7 +735,47 @@ $main-color: #23303D; ...@@ -693,7 +735,47 @@ $main-color: #23303D;
position: relative; position: relative;
width: 100%; width: 100%;
height: 130px; height: 130px;
// background-color: #d41323; }
.box_toottip {
position: absolute;
display: none;
padding: 5px 8px;
top: -35%;
left: 0 !important;
height: auto;
background-color: #fff;
border-radius: 4px;
z-index: 2000;
box-shadow: 0px 0px 5px 1px rgba($color: #666666, $alpha: 0.7);
}
.box_toottip.active {
display: block !important;
}
.overlay_box_tooltip {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
background-color: rgba($color: #000000, $alpha: 0.7);
}
.btn_login_tooltip {
background-color: #ffc107;
color: #333;
padding: 5px;
float: right;
font-size: 14px;
border-radius: 4px;
&:hover {
text-decoration: none;
color: #000;
}
&:focus {
.box_toottip {
display: block;
}
}
} }
.coc { .coc {
height: 13px; height: 13px;
...@@ -817,7 +899,8 @@ $main-color: #23303D; ...@@ -817,7 +899,8 @@ $main-color: #23303D;
} }
.box_text_five_jobs.box_padding_city { .box_text_five_jobs.box_padding_city {
background-image: linear-gradient(to right, #86cb49, #169b74, #86cb49); // background-image: linear-gradient(to right, #86cb49, #169b74, #86cb49);
background-image: linear-gradient(to right, #cc2b5e, #753a88);
color: white; color: white;
font-weight: 600; font-weight: 600;
margin-bottom: 0px !important; margin-bottom: 0px !important;
...@@ -844,6 +927,11 @@ $main-color: #23303D; ...@@ -844,6 +927,11 @@ $main-color: #23303D;
color: unset; color: unset;
} }
} }
.link_ct.apply_job {
&:hover {
color: blue !important;
}
}
.ct_name { .ct_name {
cursor: pointer; cursor: pointer;
color: white; color: white;
...@@ -872,6 +960,239 @@ $main-color: #23303D; ...@@ -872,6 +960,239 @@ $main-color: #23303D;
margin: auto; margin: auto;
text-align: center; text-align: center;
} }
// City
.box_option_location {
z-index: 1;
position: relative;
margin: 100px auto 50px;
padding: 25px 25px;
width: 70%;
height: auto;
box-shadow: 0px 1px 10px 1px #c9c9c9e8;
background-color: rgba($color: #fff, $alpha: 0.9);
// border-radius: 4px;
// border: 1px solid rgba($color: #000000, $alpha: 0.5)
}
.icon_box_option_location {
position: absolute;
top: -25%;
left: 50%;
transform: translateX(-50%);
width: 100px;
height: 100px;
border-radius: 50%;
border: 6px solid #fff;
box-shadow: 0px 0px 10px 1px #aca9a9e8;
background-color: #fff000;
background-image: linear-gradient(315deg, #fff000 0%, #ed008c 74%);
z-index: 20;
text-align: center;
}
.kl_icon_box_option_location {
color: white;
font-size: 58px;
}
.box_option_location_header {
text-align: center;
font-size: 26px;
margin: 30px 0px 20px;
}
.btn_option_location {
width: 100%;
height: 50px;
margin-bottom: 10px;
outline: none;
border: none;
border-radius: 4px;
color: white;
font-size: 18px;
background-color: #06bcfb;
background-image: linear-gradient(315deg, #06bcfb 0%, #4884ee 74%);
&:hover {
font-weight: bold;
border: 1px solid #5de6de;
background-color: #fff000;
background-image: linear-gradient(315deg, #fff000 0%, #ed008c 74%);
}
&:focus {
outline: none;
}
}
.title_list_city {
height: 50px;
width: 100%;
border-radius: 4px;
background-color: #fff000;
background-image: linear-gradient(315deg, #fff000 0%, #ed008c 74%);
box-shadow: 0px 0px 5px 2px rgba($color: #c0c0c0, $alpha: 0.3);
margin: 40px 0px;
padding-left: 20px;
span {
line-height: 50px;
color: #fff;
font-size: 18px;
font-weight: 600;
}
}
.box_cityjobs {
position: relative;
width: 100%;
height: 100px;
text-align: center;
padding: 25px 20px;
margin-bottom: 20px;
overflow: hidden;
transition: 0.2s;
background-color: #fff;
box-shadow: 0px 0px 5px 2px rgba($color: #000000, $alpha: 0.2);
&::before {
position: absolute;
content: 'Hot';
width: 80px;
height: 18px;
color: #fff;
line-height: 18px;
background-image: linear-gradient(315deg, #ff4e00 0%, #ec9f05 74%);
transform: rotate(-45deg) translateY(-10px) translateX(-25px);
top: 0;
left: 0;
}
&:hover {
transition: 0.2s;
transform: scale(1.05);
}
}
.box_cityjobs_name {
font-size: 18px;
font-weight: 600;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
.cityjobs_link {
line-height: 18px;
color: black;
&:hover {
text-decoration: none;
color: unset;
}
}
// End city
// begin detail
.banner_detail {
width: 100%;
height: 300px;
background-image: url('11');
background-repeat: no-repeat;
background-size: cover;
}
.breadcrumb li a{
text-decoration: none;
&:hover {
text-decoration: none !important;
}
}
.job_title {
h1 {
font-size: 30px;
}
}
.btn-apply_job {
margin-top: 20px;
width: 100%;
height: 100%;
color: #fff;
background-color: #d4418e;
background-image: linear-gradient(315deg, #d4418e 0%, #0652c5 74%);
outline: none !important;
border: none !important;
&:hover {
color: #fff !important;
font-weight: 600 !important;
}
}
.btn-apply_job_favorite {
margin-top: 20px;
width: 100%;
height: 100%;
color: #fff;
background-color: #fc9842;
background-image: linear-gradient(315deg, #fc9842 0%, #fe5f75 74%);
outline: none !important;
border: none !important;
&:hover {
color: #fff !important;
font-weight: 600 !important;
}
}
.box_detail_jobs {
width: 100%;
height: auto;
margin: 20px 0px 20px;
padding: 20px;
box-shadow: 0px 0px 5px 2px rgba($color: #000000, $alpha: 0.2);
}
.link_optimize {
&::after {
content: '';
position: relative;
border-right: 1px solid rgba($color: #000000, $alpha: 0.4);
width: 1px;
height: 20px;
top: 0;
right: -2px;
}
&:last-child {
&::after {
content: '';
position: relative;
border-right: 0px solid black !important;
width: 0px;
height: 0px;
top: 0;
}
}
}
.detail_info {
margin: 6px 0px !important;
span {
color: #666;
}
}
.welfare-list {
display: flex;
list-style: none;
flex-wrap: wrap;
li {
margin: 5px 0px;
flex-basis: 33.22% !important;
flex-shrink: 1;
justify-content: space-between;
}
}
.breadcrumb_total_search {
background-color: #e9ecef;
height: 48px;
font-size: 16px;
line-height: 48px;
border-radius: 4px;
max-width: 970px;
margin: 0px auto 20px;
padding: 0px 0px 0px 20px;
}
// end detail
@media only screen and (min-width: $breakpoint-tablet) { @media only screen and (min-width: $breakpoint-tablet) {
.btn_search_submit { .btn_search_submit {
width: 101%; width: 101%;
...@@ -924,6 +1245,29 @@ $main-color: #23303D; ...@@ -924,6 +1245,29 @@ $main-color: #23303D;
background-color: white; background-color: white;
margin-bottom: 10px; margin-bottom: 10px;
} }
.icon_box_option_location {
top: -20% !important;
}
}
.breadcrumb_total_search_pagination_jobs {
background-color: transparent;
height: 48px;
font-size: 16px;
line-height: 48px;
border-radius: 4px;
max-width: 970px;
margin: 20px auto 20px;
padding: 0px 0px 0px 20px;
}
.pagination_jobs {
float: right;
}
.btn_dis{
&:hover {
color: #666 !important;
background-color: transparent !important;
border: 1px solid lightgray !important;
}
} }
@media only screen and (max-width: 768px) { @media only screen and (max-width: 768px) {
...@@ -936,6 +1280,10 @@ $main-color: #23303D; ...@@ -936,6 +1280,10 @@ $main-color: #23303D;
font-size: 23px; font-size: 23px;
} }
} }
.box_option_location_header {
font-size: 20px;
}
} }
......
.box_link_favotite {
position: relative;
width: 100%;
height: 100%;
padding: 10px 10px;
span {
color: #999;
}
}
.block_link_favorite :hover {
color: #e62958;
}
.block_link_favorite.md {
display: none;
}
.link_favorite {
color: #999;
z-index: 100000;
&:hover {
text-decoration: none;
}
}
.block_click_favorite {
color: #999;
cursor: pointer;
}
.block_click_favorite.md {
display: none;
}
.link_favorite_top {
position: absolute;
z-index: 1;
// position: relative;
padding: 15px 20px;
top: 0;
right: 0;
}
.overlay_login {
visibility: hidden;
opacity: 0;
transition: 0.5;
position: fixed;
z-index: 99999;
top: 0;
bottom: 0;
left: 0;
right: 0;
transition: linear 0.2s;
background-color: rgba($color: #000000, $alpha: 0.5);
}
.overlay_login.show {
opacity: 1;
visibility: visible;
transition: linear 0.2s;
}
.modal_login {
position: absolute;
overflow: hidden;
top: 50%;
left: 50%;
height: 300px;
width: 600px;
transform: translateY(-50%) translateX(-50%);
background-color: #fff;
border-radius: 5px;
transition: cubic-bezier(0.165, 0.84, 0.44, 1);
}
// modal
.icon_close_modal_login {
cursor: pointer;
float: right;
transform: translateX(-10px);
font-size: 22px;
font-weight: 100;
color: rgba($color: #999, $alpha: 0.9);
span {
}
}
.modal_login_notice_text {
text-align: center;
color: #666;
font-size: 19px;
color: rgb(60, 71, 121);
span {
}
}
.modal_login_header {
background-color: #eee;
height: 50px;
line-height: 50px;
text-align: center;
font-size: 18px;
color: #333;
font-weight: 600;
font-family: 'Raleway', sans-serif;
}
@media only screen and (max-width: 768px) {
.block_link_favorite.lg {
display: none;
}
.block_click_favorite.lg {
display: none;
}
.block_link_favorite.md {
display: block;
}
.block_click_favorite.md {
display: block;
}
.pagination li a {
font-size: 14px !important;
}
.modal_login {
width: 95vw;
font-size: 14px;
}
.modal_login_header {
font-size: 15px;
}
.icon_close_modal_login {
font-size: 15px;
}
}
@media only screen and (max-width: 576px) {
.pagination li a {
font-size: 13px !important;
}
}
.box_content_404 {
width: 100vw;
height: 100vh;
z-index: 2000;
// height: 900px;
position: fixed;
top: 60px;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
}
.box_content_404_img {
margin: auto;
width: 700px
}
.img_404 {
width: 100%;
}
.box_content_404_text {
text-align: center;
span {
font-size: 30px;
font-weight: 800;
color: #99a6d5;
}
}
.box_content_404_back_to_home {
text-align: center;
a {
font-size: 22px;
color: #1a2c55;
&:hover {
text-decoration: none;
color: red;
}
}
}
\ No newline at end of file
// Place all the styles related to the Errors 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 industry 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 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;
}
.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;
}
\ No newline at end of file
...@@ -3,4 +3,10 @@ class ApplicationController < ActionController::Base ...@@ -3,4 +3,10 @@ class ApplicationController < ActionController::Base
require 'open-uri' require 'open-uri'
include CrawlerHelper include CrawlerHelper
def page_not_found
respond_to do |format|
format.html { render template: 'errors/not_found_error', layout: 'layouts/application', status: 404 }
format.all { render nothing: true, status: 404 }
end
end
end end
class ApplyJobController < ApplicationController
def new
url = request.url
job_id = url.scan(/[0-9]{1,8}$/).last.to_i
if Job.where(id: job_id).blank?
render 'errors/file_not_found'
else
@data_job = Job.find(job_id)
session[:job_id] = @data_job.id
session[:job_name] = @data_job.name
session[:company] = @data_job.company.name
end
end
def show
@data = params[:session]
end
def create
end
end
class CityController < ApplicationController
def index
@data_jobs_vn = City.top_hot_vn
@data_jobs_qt = City.top_hot_qt
end
end
class ErrorsController < ApplicationController
def file_not_found
render 'errors/file_not_found'
end
def unprocessable
end
def internal_server_error
end
end
class HomeController < ApplicationController class HomeController < ApplicationController
add_breadcrumb "Trang chủ", :root_path
def index def index
@industries = Industry.sort_asc.all @industries = Industry.sort_asc.all
@job_count = Job.all.count @job_count = Job.all.count
@five_jobs = Job.order(created_at: :asc).where(newdata: 1).limit(5) @five_jobs = Job.order(created_at: :desc).limit(5)
@cities = City.all @cities = City.all
@top_city = City.top_hot.take(11) @top_city = City.top_hot.take(11)
@top_industry = Industry.top_hot.take(11) @top_industry = Industry.top_hot.take(11)
......
class IndustryController < ApplicationController
def index
@data_industries_hot = Industry.top_hot
end
end
class JobController < ApplicationController
def index
end
def detail
add_breadcrumb "Trang chủ&nbsp;".html_safe, root_path
@job = Job.find(params[:id])
city = []
industry = []
@job.cities.each do |val|
city << val.name
end
@job.industries.each do |val|
industry << val.name
end
add_breadcrumb "&nbsp;#{city[0]}&nbsp;".html_safe, "/jobs/city/#{city[0]}"
add_breadcrumb "&nbsp;#{industry[0]}&nbsp;".html_safe, "/jobs/industry/#{industry[0]}"
add_breadcrumb "&nbsp;#{@job.name}".html_safe
end
def find_data_by_industry
@industries = Industry.sort_asc.all
@cities = City.all
id_industry = Industry.find_by(name: params[:key_industry])
@fill_data = id_industry.jobs.page(params[:page])
render 'result_data'
end
def find_data_by_city
@industries = Industry.sort_asc.all
@cities = City.all
id_city = City.find_by(name: params[:key_city])
@fill_data = id_city.jobs.page(params[:page])
render 'result_data'
end
def find_data_by_company
@industries = Industry.sort_asc.all
@cities = City.all
company = Company.find_by(name: params[:key_company])
@fill_data = company.jobs.page(params[:page])
render 'result_data'
end
end
module ApplyJobHelper
end
module CityHelper
end
module ErrorsHelper
end
module IndustryHelper
end
module JobHelper
end
...@@ -10,4 +10,24 @@ class City < ApplicationRecord ...@@ -10,4 +10,24 @@ class City < ApplicationRecord
end end
hash.sort_by { |k,v| v }.reverse hash.sort_by { |k,v| v }.reverse
end end
def self.top_hot_vn
hash = {}
data_cities = City.select('*').where('area = 1')
data_cities.each do |val|
hash[val.name] = val.jobs.count
end
hash = hash.select { |k,v| v > 0}
hash.sort_by { |k,v| v }.reverse
end
def self.top_hot_qt
hash = {}
data_cities = City.select('*').where('area = 0')
data_cities.each do |val|
hash[val.name] = val.jobs.count
end
hash = hash.select { |k,v| v > 0}
hash.sort_by { |k,v| v }.reverse
end
end end
...@@ -9,6 +9,7 @@ class Industry < ApplicationRecord ...@@ -9,6 +9,7 @@ class Industry < ApplicationRecord
data_industries.each do |val| data_industries.each do |val|
hash[val.name] = val.jobs.count hash[val.name] = val.jobs.count
end end
hash = hash.select { |k,v| v > 0}
hash.sort_by { |k,v| v }.reverse hash.sort_by { |k,v| v }.reverse
end end
end end
<div class="ribbon">
<div class="ribbon_name_job">
<h5><span class="span_first">Ứng tuyển vị trí:</span> <%= @data_job.name %></h5>
<h6><%= @data_job.company.name %></h6>
</div>
<hr>
<div class="row">
<div class="col-lg-4 col-md-4">
<div class="ribbon_item active">
<span class="custom_badges active">1</span> Nhập thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item">
<span class="custom_badges">2</span> Xác nhận thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item">
<span class="custom_badges">3</span> Hoàn thành
</div>
</div>
</div>
<hr>
</div>
\ No newline at end of file
<h1>ApplyJob#create</h1>
<p>Find me in app/views/apply_job/create.html.erb</p>
<!-- <%=session[:job_id]%> -->
<div class="container">
<div class="box_job_apply">
<div class="ribbon">
<div class="ribbon_name_job">
<h5><span class="span_first">Ứng tuyển vị trí:</span> <%= @data_job.name %></h5>
<h6><%= @data_job.company.name %></h6>
</div>
<hr>
<div class="row">
<div class="col-lg-4 col-md-4">
<div class="ribbon_item active">
<span class="custom_badges active">1</span> Nhập thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item">
<span class="custom_badges">2</span> Xác nhận thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item">
<span class="custom_badges">3</span> Hoàn thành
</div>
</div>
</div>
<hr>
</div>
<div class="form_apply_job">
<span class="span_second">Điền thông tin liên hệ của bạn và chọn hồ sơ để ứng tuyển:</span>
<br><br>
<span>Thông tin liên hệ của bạn</span>
<%= form_for(:session, url: confirm_path) do |f| %>
<%= f.hidden_field :user_id, value: 1 %>
<%= f.hidden_field :job_id, value: @data_job.id %>
<%= f.text_field :name %>
<%= f.text_field :email %>
<%= f.submit %>
<% end %>
</div>
</div>
</div>
\ No newline at end of file
<div class="container">
<div class="box_job_apply">
<div class="ribbon">
<div class="ribbon_name_job">
<h5><span class="span_first">Ứng tuyển vị trí:</span> <%= session[:job_name] %></h5>
<h6><%= session[:company] %></h6>
</div>
<hr>
<div class="row">
<div class="col-lg-4 col-md-4">
<div class="ribbon_item active">
<span class="custom_badges active">1</span> Nhập thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item active">
<span class="custom_badges active">2</span> Xác nhận thông tin
</div>
</div>
<div class="col-lg-4 col-md-4">
<div class="ribbon_item">
<span class="custom_badges">3</span> Hoàn thành
</div>
</div>
</div>
<hr>
</div>
<div class="form_apply_job">
<span class="span_second">Vui lòng xác nhận lại thông tin của bạn</span>
<br><br>
<span class="span_second">Họ và tên: <%= @data[:name] %> </span><br>
<span class="span_second">Email : <%= @data[:email] %> </span><br>
<span class="span_second">CV : </span><br>
<%= link_to 'Edit', :back %>
</div>
</div>
</div>
<div class="box_cityjobs">
<div class="box_cityjobs_name">
<%= link_to name_city, "jobs/city/#{name_city}",class: 'cityjobs_link' %>
</div>
<div class="box_cityjobs_count">
<span><%= jobs_count %> Công việc</span>
</div>
</div>
\ No newline at end of file
<div class="box_cityjobs">
<div class="box_cityjobs_name">
<%= link_to name_city, "jobs/city/#{name_city}",class: 'cityjobs_link' %>
</div>
<div class="box_cityjobs_count">
<span><%= jobs_count %> Công việc</span>
</div>
</div>
\ No newline at end of file
<% provide(:title,'Top thành phố') %>
<%= render 'shared/scroll_top' %>
<div class="container">
<div class="box_option_location">
<div class="icon_box_option_location">
<span class="kl_icon_box_option_location">
<i class="fas fa-search-location"></i>
</span>
</div>
<div class="row">
<div class="col-lg-12">
<div class="box_option_location_header">
<span>Bạn muốn tìm việc trong hay ngoài nước?</span>
</div>
</div>
<div class="col-lg-6">
<button class="btn_option_location btn_option_location-vn">Việt Nam</button>
</div>
<div class="col-lg-6">
<button class="btn_option_location btn_option_location-qt">Nước ngoài</button>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="title_list_city title_list_city_vn">
<span>Các tỉnh, thành phố thuôc Việt Nam</span>
</div>
</div>
<div class="container">
<div class="row">
<% @data_jobs_vn.each do |k,v| %>
<div class="col-lg-3 col-md-4">
<%= render 'block_cityjobs_vn', name_city: k, jobs_count: v %>
</div>
<% end %>
</div>
</div>
<div class="col-lg-12">
<div class="title_list_city title_list_city_qt">
<span>Quốc tế</span>
</div>
</div>
<div class="container">
<div class="row">
<% @data_jobs_qt.each do |k,v| %>
<div class="col-lg-3 col-md-4">
<%= render 'block_cityjobs_qt', name_city: k, jobs_count: v %>
</div>
<% end %>
</div>
</div>
</div>
</div>
<div class="box_content_404">
<div class="container">
<div class="col-lg-12">
<div class="box_content_404_img">
<%= image_tag '404', class: "img_404"%>
</div>
</div><br>
<div class="col-lg-12">
<div class="box_content_404_text">
<span>Chúng tôi không tìm thấy trang bạn bạn yêu cầu!</span>
</div>
</div>
<div class="col-lg-12">
<div class="box_content_404_back_to_home">
<%= link_to 'Cùng mình quay lại trang chủ nhé', root_path %>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="box_content_404">
<div class="container">
<div class="col-lg-12">
<div class="box_content_404_img">
<%= image_tag '500', class: "img_404"%>
</div>
</div><br>
<div class="col-lg-12">
<div class="box_content_404_text">
<span>Có vài lỗi trong đường dẫn này<br>
Đừng lo lắng! Xin lỗi bạn vì sự bất tiện trên
</span>
</div>
</div>
<div class="col-lg-12">
<div class="box_content_404_back_to_home">
<%= link_to 'Cùng mình quay lại trang chủ nhé', root_path %>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="box_content_404">
<div class="container">
<div class="col-lg-12">
<div class="box_content_404_img">
<%= image_tag '422', class: "img_404"%>
</div>
</div><br>
<div class="col-lg-12">
<div class="box_content_404_text">
<span>Xin lỗi bạn<br>
Máy chủ của chúng tôi đang gặp sự cố!
</span>
</div>
</div>
<div class="col-lg-12">
<div class="box_content_404_back_to_home">
<%= link_to 'Cùng mình quay lại trang chủ nhé', root_path %>
</div>
</div>
</div>
</div>
\ No newline at end of file
...@@ -17,7 +17,11 @@ ...@@ -17,7 +17,11 @@
<div class="box-search"> <div class="box-search">
<div class="search_scaffold"> <div class="search_scaffold">
<div class = "total_job"> <div class = "total_job">
<h4 class="show_total_job">Khám phá ngay <b><%=@job_count%></b> việc làm tốt nhất trên VenJob</h4> <% if @job_count.blank? %>
<h4 class="show_total_job">Khám phá ngay những việc làm tốt nhất trên VenJob</h4>
<% else %>
<h4 class="show_total_job">Khám phá ngay <b><%= @job_count%></b> việc làm tốt nhất trên VenJob</h4>
<% end %>
</div> </div>
<div class="filter_box"> <div class="filter_box">
<div class="search_input"> <div class="search_input">
......
...@@ -7,5 +7,6 @@ ...@@ -7,5 +7,6 @@
<%= render 'shared/box_five_job' %> <%= render 'shared/box_five_job' %>
<%= render 'shared/box_nine_city' %> <%= render 'shared/box_nine_city' %>
<%= render 'shared/box_nine_industries' %> <%= render 'shared/box_nine_industries' %>
<%= render 'shared/scroll_top' %>
<div class="box_cityjobs">
<div class="box_cityjobs_name">
<%= link_to industry, "jobs/industry/#{industry}",class: 'cityjobs_link' %>
</div>
<div class="box_cityjobs_count">
<span><%= jobs_count %> Công việc</span>
</div>
</div>
\ No newline at end of file
<% provide(:title,'Top nghành') %>
<%= render 'shared/scroll_top' %>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="title_list_city title_list_city_vn">
<span>Top nghành</span>
</div>
</div>
<div class="container">
<div class="row">
<% @data_industries_hot.each do |k,v| %>
<div class="col-lg-3 col-md-4">
<%= render 'block_industries_hot', industry: k, jobs_count: v %>
</div>
<% end %>
</div>
</div>
</div>
</div>
<%cru = 0%>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="box_jobs">
<div class="col-sm-12 d-block d-sm-none">
<% if cru == 1 %>
<div class="link_favorite_top block_link_favorite md">
<span><%= link_to '<i class="far fa-heart"></i>'.html_safe,'#',class: 'link_favorite'%><span>
</div>
<% else %>
<div class="block_click_favorite link_favorite_top ">
<span><i class="far fa-heart"></i><span>
</div>
<% end %>
</div>
<div class="row">
<div class="col-sm-10 col-md-9 col-lg-10">
<div class="box_info">
<div class="lol">
<%= link_to data.name, "/detail/#{data.id}" , class: 'job_name' %>
</div>
<div class="cop">
<h5 class="box_info_copany_name"><i class="far fa-building"></i> <%= data.company.name %></h5>
</div>
<div class="loc">
<h5 class="box_info_location"><i class="fas fa-map-marker-alt"></i>
<% dt = [] %>
<% data.cities.each do |x| %>
<% dt << (x.name << ' | ') %>
<% end %>
<%= dt.join('').chomp('| ')%>
</h5>
</div>
<h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp; Lương: <%= data.salary %></h5>
<div class="coc">
<h5 class="box_info_des"><%= strip_tags(data.description) %></h5>
</div>
</div>
</div>
<div class="col-sm-2 col-md-3 d-none d-sm-block col-lg-2">
<% if cru == 1 %>
<div class="box_link_favotite">
<div class="block_link_favorite lg">
<span><i class="far fa-heart"></i> <%= link_to 'Yêu thích'.html_safe,'#',class: 'link_favorite'%><span>
</div>
<div class="block_link_favorite md">
<span><%= link_to '<i class="far fa-heart"></i>'.html_safe,'#',class: 'link_favorite'%><span>
</div>
</div>
<% else %>
<div class="box_link_favotite">
<div class="block_click_favorite lg">
<span><i class="far fa-heart"></i> Yêu thích<span>
</div>
<div class="block_click_favorite md">
<span><i class="far fa-heart"></i><span>
</div>
</div>
<% end %>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
<div class="overlay_login">
<div class="modal_login">
<div class="modal_login_header">
<span>VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY</span>
<span class="icon_close_modal_login">
<i class="fas fa-times"></i>
</span>
</div>
<div class="container">
<div class="row">
<div class="col-lg 12">
<div class="modal_login_notice_text">
<span>ĐĂNG NHẬP</span>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
<!-- <%=session[:job_id]%> -->
<div class="container">
<div class="box_job_apply">
<%= render 'ribbon' %>
<div class="form_apply_job">
<span class="span_second">Điền thông tin liên hệ của bạn và chọn hồ sơ để ứng tuyển:</span>
<br><br>
<span>Thông tin liên hệ của bạn</span>
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.hidden_field :user_id, value: 1 %>
<%= f.hidden_field :job_id, value: session[:job_id] %>
<%= f.text_field :name %>
<%= f.text_field :email%>
<%= f.submit %>
<% end %>
</div>
</div>
</div>
\ No newline at end of file
<% provide(:title, @job.name) %>
<div class="container">
<div class="banner_detail">
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<%= render_breadcrumbs :tag => :li, :separator => "/" %>
</ol>
</nav>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-9">
<div class="job_title">
<h1><%= @job.name %></h1>
<span><i class="far fa-building"></i> <%= link_to @job.company.name, "/jobs/company/#{@job.company.name}",class: "link_ct apply_job"%></span>
</div>
</div>
<div class="col-lg-3 ">
<div class="btn_apply_job">
<%= link_to 'Nộp CV ngay', "/apply?job_id=#{@job.id}", class: "btn btn-apply_job" %>
</div>
</div>
<div class="col-lg-12 col-md-12">
<div class="box_detail_jobs">
<div class="box_detail_jobs_location">
<span><i class="fas fa-map-marker-alt"></i> Địa điểm làm việc: </span>
<% dt = [] %>
<% @job.cities.each do |x| %>
<%= link_to "&nbsp;#{x.name}&nbsp;".html_safe , "/jobs/city/#{x.name}", class: "link_ct apply_job link_optimize"%>
<% end %>
</div>
<div class="box_detail_jobs_salary">
<br>
<div class="row">
<div class="col-lg-4 col-md-6">
<div class="detail_info">
<span><i class="fab fa-linode"></i> Lương: <%= @job.salary%></span>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="detail_info">
<span><i class="fab fa-linode"></i> Ngày đăng tin: <%=@job.created_at.strftime('%d - %m - %Y')%></span>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="detail_info">
<% if @job.expiration_date.present? %>
<span><i class="fab fa-linode"></i> Ngày hết hạn: <%=@job.expiration_date.strftime('%d - %m - %Y')%></span>
<% else %>
<span><i class="fab fa-linode"></i> Ngày hết hạn: đang cập nhật</span>
<% end %>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="detail_info">
<span><i class="fab fa-linode"></i> Kinh nghiệm: <%=@job.experience%></span>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="detail_info">
<span><i class="fab fa-linode"></i> Cấp bậc: <%= "#{@job.level}" %></span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-12 col-md-12">
<div class="box_detail_jobs">
<% if @job.description.include?('div') %>
<%= @job.description.html_safe %>
<% else %>
<pre class="pre_desc"><%= @job.description %></pre>
<% end %>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-md-6">
<div class="btn_apply_job">
<%= link_to 'Nộp CV ngay', '#', class: "btn btn-apply_job" %>
</div>
</div>
<div class="col-lg-6 col-md-6">
<div class="btn_apply_job">
<%= link_to 'Yêu thích', '#', class: "btn btn-apply_job_favorite" %>
</div>
</div>
</div>
</div>
<%= render 'shared/scroll_top' %>
\ No newline at end of file
<% provide(:title ,'Kết quả tìm kiếm') %>
<%= render 'home/banner_and_search' %>
<div class="padding_index"></div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="breadcrumb_total_search">
<% if params[:key_city].present? %>
<span class="breadcrumb-item active">&nbsp;<b><%= @fill_data.total_count %></b>&nbsp;kết quả phù hợp với từ khóa&nbsp;<b><%= params[:key_city] %></b>&nbsp;</span>
<% elsif params[:key_industry].present? %>
<span class="breadcrumb-item active">&nbsp;<b><%= @fill_data.total_count%></b>&nbsp;kết quả phù hợp với từ khóa&nbsp;<b><%= params[:key_industry] %></b>&nbsp;</span>
<% else %>
<span class="breadcrumb-item active">&nbsp;<b><%= @fill_data.total_count%></b>&nbsp;kết quả phù hợp với từ khóa&nbsp;<b><%= params[:key_company] %></b>&nbsp;</span>
<% end %>
</div>
</div>
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div class="paginator">
<%= paginate @fill_data, :exclude => [:first, :last] %>
</div>
</div>
</div>
</div>
</div>
</div>
<%= render 'job/modal_login'%>
<% @fill_data.each do |item| %>
<%= render 'block_info_job', data: item%>
<%end%>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="breadcrumb_total_search_pagination_jobs">
<div class="pagination_jobs">
<div class="paginator">
<%= paginate @fill_data%>
</div>
</div>
</div>
</div>
</div>
</div>
<%= render 'shared/scroll_top' %>
\ No newline at end of file
<li class="page-item">
<!-- <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link' %> -->
<%= link_to_unless current_page.first?, raw(t 'Trang đầu'), url, remote: remote, class: 'page-link' %>
</li>
<!-- <li>
<%= t('views.pagination.truncate').html_safe %>
</li> -->
<!-- <li class='page-item disabled'>
<%= link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link' %>
</li> -->
<li class="page-item">
<%= link_to_unless current_page.last?, raw(t 'Trang cuối'), url, remote: remote, class: 'page-link' %>
<!-- <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link' %> -->
</li>
<!-- <li class="page-next">
<%= link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, :rel => 'next', :remote => remote %>
</li> -->
\ No newline at end of file
<!-- <li class="page-item">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link' %>
</li> -->
<li class="page<%= 'current' if page.current? %>">
<% if page.current? %>
<%= link_to page, "#" %>
<% else %>
<%= link_to_unless page.current?, page, url, {:remote => remote, :rel => page.rel} %>
<% end %>
</li>
<% if page.current? %>
<li class="page-item active">
<%= content_tag :a, page, data: { remote: remote }, rel: page.rel, class: 'page-link' %>
</li>
<% else %>
<li class="page-item">
<%= link_to page, url, remote: remote, rel: page.rel, class: 'page-link' %>
</li>
<% end %>
<%= paginator.render do %>
<div class="pagination">
<ul>
<%= prev_page_tag unless current_page.first? %>
<li>
<ul>
<% each_page do |page| %>
<% if page.left_outer? || page.right_outer? || page.inside_window? %>
<%= page_tag page %>
<% elsif !page.was_truncated? %>
<%= gap_tag %>
<% end %>
<% end %>
</ul>
</li>
<%= next_page_tag unless current_page.last? %>
</ul>
</div>
<% end %>
\ No newline at end of file
<%= paginator.render do %>
<nav>
<ul class="pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| %>
<% if page.left_outer? || page.right_outer? || page.inside_window? %>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end %>
<% end %>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</ul>
</nav>
<% end %>
<li class="page-prev">
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, :rel => 'prev', :remote => remote %>
</li>
\ No newline at end of file
<!-- <li class="page-item">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link' %>
</li> -->
...@@ -4,10 +4,11 @@ ...@@ -4,10 +4,11 @@
<title><%= full_title(yield(:title)) %></title> <title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= favicon_link_tag 'icontitle' %>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
<%= csp_meta_tag %> <%= csp_meta_tag %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/js/all.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.7/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.7/css/all.css">
<link href="https://fonts.googleapis.com/css2?family=Raleway:wght@200&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Raleway:wght@200&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Raleway&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Raleway&display=swap" rel="stylesheet">
...@@ -20,8 +21,6 @@ ...@@ -20,8 +21,6 @@
<%= custom_bootstrap_flash %> <%= custom_bootstrap_flash %>
<% flash.discard %> <% flash.discard %>
<%= render 'layouts/padding' %> <%= render 'layouts/padding' %>
<%= yield %> <%= yield %>
<%= render 'layouts/footer' %> <%= render 'layouts/footer' %>
</div> </div>
......
<div class="box_info_city"> <div class="box_info_city">
<div class="ct_name"> <div class="ct_name">
<%= link_to name_city, '#' ,class: 'link_ct'%> <%= link_to name_city, "/jobs/city/#{name_city}" ,class: 'link_ct'%>
</div> </div>
<div class="ct_jobs_count"> <div class="ct_jobs_count">
<%= link_to "#{jobs_count} công việc", '#' ,class: 'link_ct'%> <%= link_to "#{jobs_count} công việc", "/jobs/city/#{name_city}" ,class: 'link_ct'%>
</div> </div>
</div> </div>
\ No newline at end of file
<div class="box_info_city"> <div class="box_info_city">
<div class="ct_name"> <div class="ct_name">
<%= link_to industry, '#' ,class: 'link_ct'%> <%= link_to industry, "/jobs/industry/#{industry}",class: 'link_ct'%>
</div> </div>
<div class="ct_jobs_count"> <div class="ct_jobs_count">
<%= link_to "#{jobs_count} công việc", '#' ,class: 'link_ct'%> <%= link_to "#{jobs_count} công việc", "/jobs/industry/#{industry}",class: 'link_ct'%>
</div> </div>
</div> </div>
\ No newline at end of file
<%= render 'job/modal_login'%>
<%cru = 0%>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<% i = 0%>
<% @five_jobs.each do |val| %> <% @five_jobs.each do |val| %>
<div class="box_jobs"> <div class="box_jobs">
<div class="col-sm-12 d-block d-sm-none"> <div class="col-sm-12 d-block d-sm-none">
<button type="submit" class="btn_favorite_outline xs"> <% if cru == 1 %>
<i class="far fa-heart"></i> <div class="link_favorite_top block_link_favorite md">
</button> <span><%= link_to '<i class="far fa-heart"></i>'.html_safe,'#',class: 'link_favorite'%><span>
</div>
<% else %>
<div class="block_click_favorite link_favorite_top ">
<span><i class="far fa-heart"></i><span>
</div>
<% end %>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-10 col-md-9 col-lg-10"> <div class="col-sm-10 col-md-9 col-lg-10">
<div class="box_info"> <div class="box_info">
<div class="lol"> <div class="lol">
<%= link_to val.name, '#', class: 'job_name' %> <%= link_to val.name, "/detail/#{val.id}" , class: 'job_name' %>
<%= image_tag 'trophy',class: 'img_job_name' %>
</div> </div>
<div class="cop"> <div class="cop">
<h5 class="box_info_copany_name"><i class="far fa-building"></i> <%= val.company.name %></h5> <h5 class="box_info_copany_name"><i class="far fa-building"></i> <%= val.company.name %></h5>
...@@ -35,30 +40,30 @@ ...@@ -35,30 +40,30 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-2 col-md-3 d-none d-sm-block col-lg-2"> <div class="col-sm-2 col-md-3 d-none d-sm-block col-lg-2">
<div class="box_btn_favotite"> <% if cru == 1 %>
<button type="submit" class="btn_favorite_outline"> <div class="box_link_favotite">
<i class="far fa-heart"></i> Yêu thích <div class="block_link_favorite lg">
</button> <span><i class="far fa-heart"></i> <%= link_to 'Yêu thích'.html_safe,'#',class: 'link_favorite'%><span>
<button type="submit" class="btn_favorite_outline small">
<i class="far fa-heart"></i>
</button>
</div> </div>
<div class="block_link_favorite md">
<span><%= link_to '<i class="far fa-heart"></i>'.html_safe,'#',class: 'link_favorite'%><span>
</div> </div>
</div>
<% else %>
<div class="box_link_favotite">
<div class="block_click_favorite lg">
<span><i class="far fa-heart"></i> Yêu thích<span>
</div>
<div class="block_click_favorite md">
<span><i class="far fa-heart"></i><span>
</div> </div>
</div> </div>
<% end %> <% end %>
</div> </div>
</div> </div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="load_all_jobs">
<%= link_to '>> Xem tất cả việc làm <<', '#', class: 'load_all_jobs_text'%>
</div> </div>
<% end %>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
<% end %> <% end %>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12"> <div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
<%= render 'shared/load_more_city' %> <%= render 'shared/load_more_industries' %>
</div> </div>
</div> </div>
</div> </div>
......
<div class="box_info_city"> <div class="box_info_city">
<div class="ct_name"> <div class="ct_name">
<%= link_to 'Xem Thêm', '#' ,class: 'link_ct'%> <%= link_to 'Xem Thêm', cities_path ,class: 'link_ct'%>
</div> </div>
<div class="ct_jobs_count"> <div class="ct_jobs_count">
<i class="fas fa-ellipsis-h"></i> <i class="fas fa-ellipsis-h"></i>
......
<div class="box_info_city">
<div class="ct_name">
<%= link_to 'Xem Thêm', industries_path ,class: 'link_ct'%>
</div>
<div class="ct_jobs_count">
<i class="fas fa-ellipsis-h"></i>
</div>
</div>
\ No newline at end of file
<div class="btn-scroll-top">
<div class="box-btn-scroll-top">
<i class="fas fa-caret-up icon-scroll"></i>
</div>
</div>
\ No newline at end of file
...@@ -10,7 +10,8 @@ module HungntVenjob ...@@ -10,7 +10,8 @@ module HungntVenjob
class Application < Rails::Application class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version. # Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2 config.load_defaults 5.2
#
config.exceptions_app = self.routes
# Settings in config/environments/* take precedence over those specified here. # Settings in config/environments/* take precedence over those specified here.
# Application configuration can go into files in config/initializers # Application configuration can go into files in config/initializers
# -- all .rb files in that directory are automatically loaded after loading # -- all .rb files in that directory are automatically loaded after loading
......
crumb :root do
link "Home", root_path
end
# crumb :projects do
# link "Projects", projects_path
# end
# crumb :project do |project|
# link project.name, project_path(project)
# parent :projects
# end
# crumb :project_issues do |project|
# link "Issues", project_issues_path(project)
# parent :project, project
# end
# crumb :issue do |issue|
# link issue.title, issue_path(issue)
# parent :project_issues, issue.project
# end
# If you want to split your breadcrumbs configuration over multiple files, you
# can create a folder named `config/breadcrumbs` and put your configuration
# files there. All *.rb files (e.g. `frontend.rb` or `products.rb`) in that
# folder are loaded and reloaded automatically when you change them, just like
# this file (`config/breadcrumbs.rb`).
\ No newline at end of file
...@@ -10,8 +10,8 @@ Rails.application.configure do ...@@ -10,8 +10,8 @@ Rails.application.configure do
config.eager_load = false config.eager_load = false
# Show full error reports. # Show full error reports.
config.consider_all_requests_local = true # config.consider_all_requests_local = true
config.consider_all_requests_local = false
# Enable/disable caching. By default caching is disabled. # Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching. # Run rails dev:cache to toggle caching.
if Rails.root.join('tmp', 'caching-dev.txt').exist? if Rails.root.join('tmp', 'caching-dev.txt').exist?
......
# frozen_string_literal: true
Kaminari.configure do |config|
config.default_per_page = 20
# config.max_per_page = nil
config.window = 2
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.max_pages = nil
# config.params_on_first_page = false
end
Rails.application.routes.draw do Rails.application.routes.draw do
get 'ftp/upload'
post 'ftp/new' get 'apply_job/create'
get 'ftp/new', to: 'ftp#index'
match '/ftp', to: 'ftp#index', via: 'get'
post 'ftp/new'
# match '/ftp', to: 'ftp#index', via: 'post'
# get 'home/index'
root 'home#index' root 'home#index'
match '/404', to: "errors#file_not_found", via: :all
match '/422', to: "errors#unprocessable", via: :all
match '/500', to: "errors#internal_server_error", via: :all
match 'apply', to: 'apply_job#new', via: :get, constraints: { job_id: /.*/}
match '/confirm', to: 'apply_job#show', via: 'post'
match 'detail/:id', to: 'job#detail', via: 'get'
match 'jobs/city/(:key_city)', to: 'job#find_data_by_city', via: 'get', constraints: { key_city: /.*/}
match 'jobs/industry/(:key_industry)', to: 'job#find_data_by_industry', via: 'get', constraints: { key_industry: /.*/}
match 'jobs/company/(:key_company)', to: 'job#find_data_by_company', via: 'get', constraints: { key_company: /.*/}
match 'cities', to: 'city#index', via: 'get'
match 'industries', to: 'industry#index', via: 'get'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end end
env :PATH, ENV['PATH']
every '53 13 23 7 *' do every 10.minutes do
rake "crawler:populate" rake "crawler:populate", output: {error: 'error.log', standard: 'cron.log'}
end end
every :day, at: "19:00pm"do
rake "csv:import_csv"
end
every :day, at: "16:30pm" do
rake "crawler:deletelog"
end
This diff is collapsed. Click to expand it.
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::Error::ConnectionError: MySQL server has gone away: SELECT `industries`.* FROM `industries` WHERE `industries`.`name` = 'Ngân hàng' LIMIT 1
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:186:in `block in make_foreign_industries_table'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:184:in `each'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:184:in `make_foreign_industries_table'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:98:in `add_data'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:130:in `crawl_data_jobs_interface_1'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:212:in `block in make_data'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `each'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `each_with_index'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `make_data'
/home/hungnt/hungnt_venjob/lib/tasks/crawler.rake:9:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Caused by:
Mysql2::Error::ConnectionError: MySQL server has gone away
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:186:in `block in make_foreign_industries_table'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:184:in `each'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:184:in `make_foreign_industries_table'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:98:in `add_data'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:130:in `crawl_data_jobs_interface_1'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:212:in `block in make_data'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `each'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `each_with_index'
/home/hungnt/hungnt_venjob/lib/src/interface_web.rb:209:in `make_data'
/home/hungnt/hungnt_venjob/lib/tasks/crawler.rake:9:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
SocketError: Failed to open TCP connection to careerbuilder.vn:443 (getaddrinfo: Temporary failure in name resolution)
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Caused by:
SocketError: getaddrinfo: Temporary failure in name resolution
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
Net::OpenTimeout: execution expired
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
Net::OpenTimeout: execution expired
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
Net::OpenTimeout: execution expired
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
Net::OpenTimeout: execution expired
/home/hungnt/venjob/lib/src/interface_web.rb:40:in `craw_data_cities'
/home/hungnt/venjob/lib/tasks/crawler.rake:7:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
ArgumentError: You should not use the `match` method in your router without specifying an HTTP method.
If you want to expose your action to both GET and POST, add `via: [:get, :post]` option.
If you want to expose your action to GET, use `get` in the router:
Instead of: match "controller#action"
Do: get "controller#action"
/home/hungnt/venjob/config/routes.rb:4:in `block in <main>'
/home/hungnt/venjob/config/routes.rb:1:in `<main>'
/home/hungnt/venjob/config/environment.rb:5:in `<main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate => environment
(See full trace by running task with --trace)
rake aborted!
NoMethodError: undefined method `rescue_from' for #<ActionDispatch::Routing::Mapper:0x000055ef745fa5a0>
Did you mean? rescue
/home/hungnt/venjob/config/routes.rb:6:in `block in <main>'
/home/hungnt/venjob/config/routes.rb:1:in `<main>'
/home/hungnt/venjob/config/environment.rb:5:in `<main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate => environment
(See full trace by running task with --trace)
rake aborted!
SyntaxError: /home/hungnt/venjob/config/routes.rb:6: syntax error, unexpected tIDENTIFIER, expecting end
...to: "errors#unprocessable'" via: :all
... ^~~
/home/hungnt/venjob/config/environment.rb:5:in `<main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate => environment
(See full trace by running task with --trace)
rake aborted!
SocketError: Failed to open TCP connection to careerbuilder.vn:443 (getaddrinfo: Temporary failure in name resolution)
/home/hungnt/venjob/lib/src/interface_web.rb:63:in `block in craw_data_companies'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each_with_index'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `craw_data_companies'
/home/hungnt/venjob/lib/tasks/crawler.rake:8:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Caused by:
SocketError: getaddrinfo: Temporary failure in name resolution
/home/hungnt/venjob/lib/src/interface_web.rb:63:in `block in craw_data_companies'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each_with_index'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `craw_data_companies'
/home/hungnt/venjob/lib/tasks/crawler.rake:8:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
SocketError: Failed to open TCP connection to careerbuilder.vn:443 (getaddrinfo: Temporary failure in name resolution)
/home/hungnt/venjob/lib/src/interface_web.rb:63:in `block in craw_data_companies'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each_with_index'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `craw_data_companies'
/home/hungnt/venjob/lib/tasks/crawler.rake:8:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Caused by:
SocketError: getaddrinfo: Temporary failure in name resolution
/home/hungnt/venjob/lib/src/interface_web.rb:63:in `block in craw_data_companies'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `each_with_index'
/home/hungnt/venjob/lib/src/interface_web.rb:62:in `craw_data_companies'
/home/hungnt/venjob/lib/tasks/crawler.rake:8:in `block (2 levels) in <main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate
(See full trace by running task with --trace)
rake aborted!
SyntaxError: /home/hungnt/hungnt_venjob/config/routes.rb:9: syntax error, unexpected tIDENTIFIER, expecting end
...tch 'apply?job_id=(:job_id)' to: 'job#new_apply', via: 'get'
... ^~
/home/hungnt/hungnt_venjob/config/environment.rb:5:in `<main>'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `load'
/home/hungnt/.rbenv/versions/2.6.6/bin/bundle:23:in `<main>'
Tasks: TOP => crawler:populate => environment
(See full trace by running task with --trace)
=> 2020-07-26 20:23:43 +0700 IMPORT SUCCESS
\ No newline at end of file
...@@ -28,9 +28,7 @@ class FtpSever ...@@ -28,9 +28,7 @@ class FtpSever
def self.parse_csv_industries(data) def self.parse_csv_industries(data)
puts 'Import data industries . . .' puts 'Import data industries . . .'
industries = [] industries = []
data['category'].each do |val| industries += data['category'].map(&:strip)
industries << val.strip
end
industries.each do |val| industries.each do |val|
val.gsub!(',','/') if val.include?(',') val.gsub!(',','/') if val.include?(',')
val.gsub!('/',' / ') val.gsub!('/',' / ')
...@@ -73,7 +71,7 @@ class FtpSever ...@@ -73,7 +71,7 @@ class FtpSever
def self.parse_csv_jobs(data) def self.parse_csv_jobs(data)
Job.update_all(newdata: 0) Job.update_all(newdata: 0)
data['name'].each_with_index do |name, index| data['name'].each_with_index do |name, index|
desc = (data['requirement'][index]).to_s + '\n' << (data['description'][index]).to_s desc = (data['requirement'][index]).to_s << (data['description'][index]).to_s
id_company = Company.find_by name: data['company name'][index].to_s.strip id_company = Company.find_by name: data['company name'][index].to_s.strip
id_company = id_company.blank? ? 1 : id_company.id id_company = id_company.blank? ? 1 : id_company.id
begin begin
......
...@@ -9,7 +9,6 @@ class InterfaceWeb ...@@ -9,7 +9,6 @@ class InterfaceWeb
file = File.readlines('tmp/link.txt', 'r') if File.exist?('tmp/link.txt') file = File.readlines('tmp/link.txt', 'r') if File.exist?('tmp/link.txt')
@@stop_crawl = file.blank? ? '' : file.join @@stop_crawl = file.blank? ? '' : file.join
File.delete('tmp/link.txt') if File.exist?('tmp/link.txt')
page.times do |i| page.times do |i|
page = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-#{i+1}-vi.html")) page = Nokogiri::HTML(URI.open("https://careerbuilder.vn/viec-lam/tat-ca-viec-lam-trang-#{i+1}-vi.html"))
...@@ -24,7 +23,8 @@ class InterfaceWeb ...@@ -24,7 +23,8 @@ class InterfaceWeb
website_jobs = website_jobs.select { |val| val.present?} website_jobs = website_jobs.select { |val| val.present?}
puts "Result:\nCompany: #{website_companies.length} link\nJob : #{website_jobs.length} link\n------------------------" puts "Result:\nCompany: #{website_companies.length} link\nJob : #{website_jobs.length} link\n------------------------"
File.open("tmp/link.txt", "w+") {|f| f.write(website_jobs[0])}
File.write("tmp/link.txt", "#{website_jobs[0]}")
data << website_companies << website_jobs data << website_companies << website_jobs
end end
...@@ -55,6 +55,7 @@ class InterfaceWeb ...@@ -55,6 +55,7 @@ class InterfaceWeb
end end
end end
@logger ||= Logger.new("#{Rails.root}/log/bug_crawler.log")
def self.craw_data_companies def self.craw_data_companies
puts 'Crawl data companies' puts 'Crawl data companies'
link_crawl = get_link_job_and_companies link_crawl = get_link_job_and_companies
...@@ -73,6 +74,7 @@ class InterfaceWeb ...@@ -73,6 +74,7 @@ class InterfaceWeb
desc = page.search(".main-about-us .content").text desc = page.search(".main-about-us .content").text
end end
begin
if (name.present? && address.present? && desc.present?) if (name.present? && address.present? && desc.present?)
Company.find_or_create_by(name: name.strip) do |company| Company.find_or_create_by(name: name.strip) do |company|
company.name = name.strip company.name = name.strip
...@@ -81,11 +83,15 @@ class InterfaceWeb ...@@ -81,11 +83,15 @@ class InterfaceWeb
end end
puts name puts name
end end
rescue => exception
@logger.error "#{exception.message} - Link: #{url}"
end
end end
end end
@logger_jobs ||= Logger.new("#{Rails.root}/log/bug_crawler_jobs.log")
def self.add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience) def self.add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience)
Job.update_all(newdata: 0) begin
id_company = Company.find_by name: company_name id_company = Company.find_by name: company_name
id_company = id_company.present? ? id_company.id : 1 id_company = id_company.present? ? id_company.id : 1
id_job = Job.create!(name: name, id_job = Job.create!(name: name,
...@@ -95,88 +101,71 @@ class InterfaceWeb ...@@ -95,88 +101,71 @@ class InterfaceWeb
salary: salary, salary: salary,
create_date: created_date, create_date: created_date,
expiration_date: expiration_date, expiration_date: expiration_date,
description: description, description: description)
newdata: 1)
make_foreign_industries_table(industry_name, id_job.id) make_foreign_industries_table(industry_name, id_job.id)
make_foreign_cities_table(city_name, id_job.id) make_foreign_cities_table(city_name, id_job.id)
rescue => exception
@logger_jobs.error "#{exception.message} - Job: #{name} - Company_id: #{id_company}"
end
end end
def self.crawl_data_jobs_interface_1(page) def self.crawl_data_jobs_interface_1(page)
name = page.search(".apply-now-content .job-desc .title").text name = page.search(".apply-now-content .job-desc .title").text
company_name = page.search(".apply-now-content .job-desc .job-company-name").text company_name = page.search(".apply-now-content .job-desc .job-company-name").text
location = [] location = []
length = page.search(".detail-box .map p a").size length = page.search(".detail-box .map p a").size
length.times do |n| length.times do |n|
location << page.search(".detail-box .map p a:nth-child(#{n+1})").text location << page.search(".detail-box .map p a:nth-child(#{n+1})").text
end end
city_name = location.join(',') city_name = location.join(',')
created_date = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[0].text created_date = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[0].text
expiration_date = page.search(".item-blue .detail-box ul li:last")[1].text.delete!("[\n,\t,\r]").split(' ').last expiration_date = page.search(".item-blue .detail-box ul li:last")[1].text.delete!("[\n,\t,\r]").split(' ').last
salary = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[1].text salary = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[1].text
industries = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(2) a").text industries = page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(2) a").text
industries = industries.delete!("[\n,\t,\r]").split(' ').select { |v| v != ''} industries = industries.delete!("[\n,\t,\r]").split(' ').select { |v| v != ''}
industry_name = industries.join(',') industry_name = industries.join(',')
description = page.search(".tabs .tab-content .detail-row:nth-child(n)").to_s
description = page.search(".tabs .tab-content .detail-row:nth-child(n)").to_s.delete!("[\n,\t,\r]")
get_level = page.search(".item-blue .detail-box:last ul li:nth-child(3)").text.delete!("[\n,\t,\r]").lstrip.split('Cấp bậc') get_level = page.search(".item-blue .detail-box:last ul li:nth-child(3)").text.delete!("[\n,\t,\r]").lstrip.split('Cấp bậc')
get_level = get_level[1].to_s.strip get_level = get_level[1].to_s.strip
if get_level == "" if get_level.blank?
g_level = page.search(".item-blue .detail-box:last ul li:nth-child(2)").text.delete!("[\n,\t,\r]").lstrip.split('Cấp bậc') g_level = page.search(".item-blue .detail-box:last ul li:nth-child(2)").text.delete!("[\n,\t,\r]").lstrip.split('Cấp bậc')
level = g_level[1].to_s.strip level = g_level[1].to_s.strip
else else
g_level = get_level g_level = get_level
level = g_level[1].to_s.strip level = g_level
end end
exp = page.search(".item-blue .detail-box:last ul li:nth-child(2)").text.delete!("[\n,\t,\r]").split('Kinh nghiệm') exp = page.search(".item-blue .detail-box:last ul li:nth-child(2)").text.delete!("[\n,\t,\r]").split('Kinh nghiệm')
exp = exp[1].to_s.strip exp = exp[1].to_s.strip
exprience = exp exprience = exp
add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience) add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience)
end end
def self.crawl_data_jobs_interface_2(page) def self.crawl_data_jobs_interface_2(page)
name = page.search(".apply-now-content .job-desc .title").text name = page.search(".apply-now-content .job-desc .title").text
company_name = page.search(".top-job .top-job-info .tit_company").text company_name = page.search(".top-job .top-job-info .tit_company").text
location = [] location = []
length = page.search(".info-workplace .value a").size length = page.search(".info-workplace .value a").size
length.times do |n| length.times do |n|
location << page.search(".info-workplace .value a:nth-child(#{n+1})").text location << page.search(".info-workplace .value a:nth-child(#{n+1})").text
end end
city_name = location.join(',') city_name = location.join(',')
created_date = "" created_date = ""
expiration_date = page.search(".info li:nth-child(4)").text expiration_date = page.search(".info li:nth-child(4)").text
if expiration_date.blank? if expiration_date.blank?
expiration_date = "" expiration_date = ""
else else
expiration_date = expiration_date.to_s.delete!("[\n,\t,\r]").split(' ').last expiration_date = expiration_date.to_s.delete!("[\n,\t,\r]").split(' ').last
end end
salary = page.search(".info li:nth-child(3)").text.split("Lương").last.strip salary = page.search(".info li:nth-child(3)").text.split("Lương").last.strip
industry_name = page.search(".info li:nth-child(5) .value").text industry_name = page.search(".info li:nth-child(5) .value").text
description = page.search(".left-col").to_s
description = page.search(".left-col").to_s.delete!("[\n,\t,\r]")
lv = page.search(".boxtp .info li:nth-child(2)").text lv = page.search(".boxtp .info li:nth-child(2)").text
if lv.blank? if lv.blank?
level = "" level = ""
else else
level = lv.delete!("[\n,\t,\r]").strip.split('Cấp bậc').last.strip level = lv.delete!("[\n,\t,\r]").strip.split('Cấp bậc').last.strip
end end
exp = page.search(".info li:nth-child(6)").text exp = page.search(".info li:nth-child(6)").text
if exp.blank? if exp.blank?
exprience = "" exprience = ""
...@@ -189,25 +178,15 @@ class InterfaceWeb ...@@ -189,25 +178,15 @@ class InterfaceWeb
def self.crawl_data_jobs_interface_5(page) def self.crawl_data_jobs_interface_5(page)
name = page.search(".info-company h1").text name = page.search(".info-company h1").text
company_name = page.search(".info-company .text-job h2").text company_name = page.search(".info-company .text-job h2").text
city_name = page.search(".DetailJobNew ul li:nth-child(1) a").text city_name = page.search(".DetailJobNew ul li:nth-child(1) a").text
created_date = "" created_date = ""
expiration_date = page.search(".DetailJobNew li:nth-child(9) span").text.strip expiration_date = page.search(".DetailJobNew li:nth-child(9) span").text.strip
salary = page.search(".DetailJobNew li:nth-child(3) span").text.strip salary = page.search(".DetailJobNew li:nth-child(3) span").text.strip
industry_name = page.search(".DetailJobNew li:nth-child(2) span").text.strip industry_name = page.search(".DetailJobNew li:nth-child(2) span").text.strip
description = page.search(".left-col .detail-row")
description = page.search(".left-col .detail-row").to_s.delete!("[\n,\t,\r]")
level = page.search(".DetailJobNew ul li:nth-child(6) span").text.strip level = page.search(".DetailJobNew ul li:nth-child(6) span").text.strip
exprience = page.search(".DetailJobNew li:nth-child(5) span").text.strip exprience = page.search(".DetailJobNew li:nth-child(5) span").text.strip
add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience) add_data(name, company_name, city_name, created_date, expiration_date, salary, industry_name, description, level, exprience)
end end
...@@ -232,20 +211,13 @@ class InterfaceWeb ...@@ -232,20 +211,13 @@ class InterfaceWeb
def self.make_data def self.make_data
puts 'Please wait for crawl jobs data! . . .' puts 'Please wait for crawl jobs data! . . .'
name = ''
company_name = ''
level = ''
exprience = ''
salary = ''
created_date = ''
expiration_date = ''
description = ''
industry_name = ''
city_name = ''
link_crawl = get_link_job_and_companies link_crawl = get_link_job_and_companies
link_crawl[1].each_with_index do |path,i| arr_link = []
break if @@stop_crawl == path link_crawl[1].each do |val|
break if @@stop_crawl == val
arr_link << val
end
arr_link.reverse!.each_with_index do |path,i|
page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(path)))) page = Nokogiri::HTML(URI.open(URI.parse(URI.escape(path))))
if page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[0] != nil if page.search(".item-blue .detail-box:nth-child(1) ul li:nth-child(1) p")[0] != nil
crawl_data_jobs_interface_1(page) crawl_data_jobs_interface_1(page)
...@@ -256,5 +228,6 @@ class InterfaceWeb ...@@ -256,5 +228,6 @@ class InterfaceWeb
end end
puts "#{i} - #{path}" puts "#{i} - #{path}"
end end
puts 'Crawler data jobs success!'
end end
end end
\ No newline at end of file
require 'open-uri' require 'open-uri'
require 'logger'
require 'src/interface_web' require 'src/interface_web'
namespace :crawler do namespace :crawler do
task populate: :environment do task populate: :environment do
InterfaceWeb.craw_data_cities()
InterfaceWeb.craw_data_companies() InterfaceWeb.craw_data_companies()
InterfaceWeb.make_data() InterfaceWeb.make_data()
File.open('log/crawler.log','a') do |f|
f.puts "#{Time.now} - INFO: Crawler data don't have error!"
end
end
task deletelog: :environment do
File.open('cron.log','w') { |file| File.truncate(file,0) }
end end
end end
require 'src/ftp' require 'src/ftp'
namespace :csv do namespace :csv do
task import_csv: :environment do task import_csv: :environment do
File.write('importcsv.log', "=> #{Time.now} IMPORT SUCCESS")
Company.find_or_create_by(name: 'Bảo mật', address: 'Vui lòng xem trong mô tả công việc') do |company| Company.find_or_create_by(name: 'Bảo mật', address: 'Vui lòng xem trong mô tả công việc') do |company|
company.name = 'Bảo mật' company.name = 'Bảo mật'
company.address = 'Vui lòng xem trong mô tả công việc' company.address = 'Vui lòng xem trong mô tả công việc'
......
namespace :user do
task fakedata: :environment do
User.create!(email: 'trunghung5055@gmail.com',
name: 'Ngô Trung Hưng',
password_digest: '1111',
admin: 1)
end
end
\ No newline at end of file
require 'test_helper'
class ApplyJobControllerTest < ActionDispatch::IntegrationTest
test "should get new" do
get apply_job_new_url
assert_response :success
end
test "should get show" do
get apply_job_show_url
assert_response :success
end
test "should get create" do
get apply_job_create_url
assert_response :success
end
end
require 'test_helper'
class CityControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get city_index_url
assert_response :success
end
end
require 'test_helper'
class ErrorsControllerTest < ActionDispatch::IntegrationTest
test "should get file_not_found" do
get errors_file_not_found_url
assert_response :success
end
test "should get unprocessable" do
get errors_unprocessable_url
assert_response :success
end
test "should get internal_server_error" do
get errors_internal_server_error_url
assert_response :success
end
end
require 'test_helper'
class IndustryControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get industry_index_url
assert_response :success
end
end
require 'test_helper'
class JobControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get job_index_url
assert_response :success
end
test "should get detail" do
get job_detail_url
assert_response :success
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