Commit e31804c7 by Hoang Phuc Do

Merge branch 'authen' into 'master'

create func login logout mypage

See merge request !9
parents fdadf9b7 eeaec5db
Pipeline #898 failed with stages
in 0 seconds
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
/yarn-error.log /yarn-error.log
/public/assets /public/assets
/public/uploads
.byebug_history .byebug_history
.env
# Ignore master key for decrypting credentials and more. # Ignore master key for decrypting credentials and more.
/config/master.key /config/master.key
/lib/csv /lib/csv
...@@ -31,6 +31,9 @@ gem 'whenever' ...@@ -31,6 +31,9 @@ gem 'whenever'
gem 'kaminari' gem 'kaminari'
gem 'breadcrumbs_on_rails' gem 'breadcrumbs_on_rails'
gem 'draper' gem 'draper'
gem 'devise'
gem 'carrierwave'
gem 'rails-i18n'
# Use ActiveStorage variant # Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8' # gem 'mini_magick', '~> 4.8'
...@@ -43,6 +46,7 @@ gem 'bootsnap', '>= 1.1.0', require: false ...@@ -43,6 +46,7 @@ gem 'bootsnap', '>= 1.1.0', require: false
group :development, :test do group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console # Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'dotenv-rails'
end end
group :development do group :development do
......
...@@ -51,6 +51,7 @@ GEM ...@@ -51,6 +51,7 @@ GEM
archive-zip (0.12.0) archive-zip (0.12.0)
io-like (~> 0.3.0) io-like (~> 0.3.0)
arel (9.0.0) arel (9.0.0)
bcrypt (3.1.15)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.4.7) bootsnap (1.4.7)
msgpack (~> 1.0) msgpack (~> 1.0)
...@@ -66,6 +67,13 @@ GEM ...@@ -66,6 +67,13 @@ GEM
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (~> 1.5) regexp_parser (~> 1.5)
xpath (~> 3.2) xpath (~> 3.2)
carrierwave (2.1.0)
activemodel (>= 5.0.0)
activesupport (>= 5.0.0)
addressable (~> 2.6)
image_processing (~> 1.1)
mimemagic (>= 0.3.0)
mini_mime (>= 0.1.3)
childprocess (3.0.0) childprocess (3.0.0)
chromedriver-helper (2.1.1) chromedriver-helper (2.1.1)
archive-zip (~> 0.10) archive-zip (~> 0.10)
...@@ -80,6 +88,16 @@ GEM ...@@ -80,6 +88,16 @@ GEM
coffee-script-source (1.12.2) coffee-script-source (1.12.2)
concurrent-ruby (1.1.6) concurrent-ruby (1.1.6)
crass (1.0.6) crass (1.0.6)
devise (4.7.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
dotenv (2.7.6)
dotenv-rails (2.7.6)
dotenv (= 2.7.6)
railties (>= 3.2)
draper (4.0.1) draper (4.0.1)
actionpack (>= 5.0) actionpack (>= 5.0)
activemodel (>= 5.0) activemodel (>= 5.0)
...@@ -93,6 +111,9 @@ GEM ...@@ -93,6 +111,9 @@ GEM
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
i18n (1.8.5) i18n (1.8.5)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
image_processing (1.11.0)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.17, < 3)
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)
...@@ -121,6 +142,7 @@ GEM ...@@ -121,6 +142,7 @@ GEM
mimemagic (~> 0.3.2) mimemagic (~> 0.3.2)
method_source (1.0.0) method_source (1.0.0)
mimemagic (0.3.5) mimemagic (0.3.5)
mini_magick (4.10.1)
mini_mime (1.0.2) mini_mime (1.0.2)
mini_portile2 (2.4.0) mini_portile2 (2.4.0)
minitest (5.14.1) minitest (5.14.1)
...@@ -129,6 +151,7 @@ GEM ...@@ -129,6 +151,7 @@ GEM
nio4r (2.5.2) nio4r (2.5.2)
nokogiri (1.10.10) nokogiri (1.10.10)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
orm_adapter (0.5.0)
public_suffix (4.0.5) public_suffix (4.0.5)
puma (3.12.6) puma (3.12.6)
rack (2.2.3) rack (2.2.3)
...@@ -152,6 +175,9 @@ GEM ...@@ -152,6 +175,9 @@ GEM
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0) rails-html-sanitizer (1.3.0)
loofah (~> 2.3) loofah (~> 2.3)
rails-i18n (5.1.3)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
railties (5.2.4.3) railties (5.2.4.3)
actionpack (= 5.2.4.3) actionpack (= 5.2.4.3)
activesupport (= 5.2.4.3) activesupport (= 5.2.4.3)
...@@ -165,6 +191,11 @@ GEM ...@@ -165,6 +191,11 @@ GEM
regexp_parser (1.7.1) regexp_parser (1.7.1)
request_store (1.5.0) request_store (1.5.0)
rack (>= 1.4) rack (>= 1.4)
responders (3.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
ruby-vips (2.0.17)
ffi (~> 1.9)
ruby_dep (1.5.0) ruby_dep (1.5.0)
rubyzip (2.3.0) rubyzip (2.3.0)
sass (3.7.4) sass (3.7.4)
...@@ -202,6 +233,8 @@ GEM ...@@ -202,6 +233,8 @@ GEM
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (4.2.0) uglifier (4.2.0)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
warden (1.2.8)
rack (>= 2.0.6)
web-console (3.7.0) web-console (3.7.0)
actionview (>= 5.0) actionview (>= 5.0)
activemodel (>= 5.0) activemodel (>= 5.0)
...@@ -223,8 +256,11 @@ DEPENDENCIES ...@@ -223,8 +256,11 @@ DEPENDENCIES
breadcrumbs_on_rails breadcrumbs_on_rails
byebug byebug
capybara (>= 2.15) capybara (>= 2.15)
carrierwave
chromedriver-helper chromedriver-helper
coffee-rails (~> 4.2) coffee-rails (~> 4.2)
devise
dotenv-rails
draper draper
jbuilder (~> 2.5) jbuilder (~> 2.5)
kaminari kaminari
...@@ -233,6 +269,7 @@ DEPENDENCIES ...@@ -233,6 +269,7 @@ DEPENDENCIES
nokogiri nokogiri
puma (~> 3.11) puma (~> 3.11)
rails (~> 5.2.4, >= 5.2.4.3) rails (~> 5.2.4, >= 5.2.4.3)
rails-i18n
sass-rails (~> 5.0) sass-rails (~> 5.0)
selenium-webdriver selenium-webdriver
spring spring
......
# 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/
!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("<div/>").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'<button type="button">&times;</button>',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&#39;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e("<div/>"),M=e("<div/>"),B=e("<div/>"),q=e("<div/>"),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.3",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)});
//# sourceMappingURL=toastr.js.map
# 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/
...@@ -117,6 +117,16 @@ $main-color: #23303D; ...@@ -117,6 +117,16 @@ $main-color: #23303D;
} }
} }
.link_item_menu_header_right.custom:hover {
color: #fff;
text-decoration: none;
}
.header_img_flag {
width: 25px;
height: 15px;
}
.menu__mobile { .menu__mobile {
position: absolute; position: absolute;
height: 100vh; height: 100vh;
...@@ -163,15 +173,19 @@ $main-color: #23303D; ...@@ -163,15 +173,19 @@ $main-color: #23303D;
} }
.link_item_menu_mobile { .link_item_menu_mobile {
font-size: 17px; font-size: 17px;
color: white; color: white;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
color: #999; color: #999;
} }
} }
.link_item_menu_mobile.custom:hover {
text-decoration: none;
color: #fff;
}
.padding_header_to_body { .padding_header_to_body {
padding-top: 52px; padding-top: 52px;
} }
...@@ -603,9 +617,7 @@ $main-color: #23303D; ...@@ -603,9 +617,7 @@ $main-color: #23303D;
transform: scale(1.2); transform: scale(1.2);
font-weight: 500; font-weight: 500;
} }
// .box-search-tablet {
// display: block;
// }
} }
@media only screen and (max-width: 660px) { @media only screen and (max-width: 660px) {
...@@ -1349,4 +1361,177 @@ $main-color: #23303D; ...@@ -1349,4 +1361,177 @@ $main-color: #23303D;
font-weight: bold; font-weight: bold;
color: rgb(211, 48, 48); color: rgb(211, 48, 48);
} }
.new_user {
width: 100%;
}
@media only screen and (min-width: 992px) {
.box_form {
width: 80% !important;
}
}
.box_form {
width: 100%;
margin: auto;
margin-top: 10vh;
margin-bottom: 35vh;
padding: 15px 50px;
height: auto;
border-radius: 6px;
box-shadow: 0px 1px 5px 2px rgba($color: #999, $alpha: 0.7);
position: relative;
overflow: hidden;
&::before {
content: '';
position: absolute;
width: 80px;
height: 20px;
background-color: red;
transform: rotate(315deg);
top: 10px;
left: -20px;
}
&::after {
content: '';
position: absolute;
width: 80px;
height: 20px;
background-color: red;
transform: rotate(135deg);
bottom: 5px;
right: -20px;
}
}
.box_btn-reg {
width: 50%;
margin: auto;
}
.box_ful_link_reg {
text-align: center;
}
#error_explanation ul li{
list-style: none;
color: red;
font-size: 15px;
font-style: italic;
}
.pppp {
width: 100% !important;
}
.list_email_app {
ul {
list-style: none;
display: flex;
}
li {
margin: 5px 15px;
&:nth-child(2) {
a {
color: red;
}
}
&:nth-child(3) {
a {
color: rgb(101, 73, 226);
}
}
&:nth-child(4) {
a {
color: rgb(25, 110, 238);
}
}
&:hover {
a {
text-decoration: none;
transition: 0.4s;
font-style: italic;
}
}
}
}
.bg_img {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-image:asset-url('11.jpg');
}
.box_my_page {
position: relative;
top: 10vh;
width: 90%;
margin: auto;
border-radius: 5px;
border: 1px solid rgba(#5d4708, 0.5);
z-index: 22;
box-shadow: 0px 1px 5px 1px rgba($color: #636363, $alpha: 0.8);
&::before {
content: '';
position: absolute;
width: 20px;
height: 300px;
background-color: #d39e00;
transform: translateY(-260px);
top: 0;
left: 8%;
}
&::after {
content: '';
position: absolute;
width: 20px;
height: 300px;
background-color: #d39e00;
transform: translateY(-260px);
top: 0;
z-index: -1;
right: 8%;
}
}
.box_my_page_header {
position: relative;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
background-color: #f1a752;
text-align: center;
height: 40px;
h4 {
font-size: 22px;
color: #000;
line-height: 40px;
}
&::before {
content: '';
position: absolute;
width: 20px;
height: 20px;
background-color: #5d4708;
border-radius: 50%;
top: 5px;
left: 8%;
}
&::after {
content: '';
position: absolute;
width: 20px;
height: 20px;
background-color: #5d4708;
border-radius: 50%;
top: 5px;
right: 8%;
}
}
.box_my_page_content {
padding: 10px 35px 20px;
font-size: 16px;
font-family: 'Raleway', sans-serif;
font-weight: bold;
}
.link_ct.pdf {
color: rgb(134, 94, 18);
}
#edit_user {
margin: auto;
}
\ No newline at end of file
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
overflow: hidden; overflow: hidden;
top: 50%; top: 50%;
left: 50%; left: 50%;
height: 300px; height: 100px;
width: 600px; width: 600px;
transform: translateY(-50%) translateX(-50%); transform: translateY(-50%) translateX(-50%);
background-color: #fff; background-color: #fff;
...@@ -82,9 +82,10 @@ ...@@ -82,9 +82,10 @@
} }
} }
.modal_login_notice_text { .modal_login_notice_text {
margin-top: 5px;
text-align: center; text-align: center;
color: #666; color: #666;
font-size: 19px; font-size: 17px;
color: rgb(60, 71, 121); color: rgb(60, 71, 121);
span { span {
...@@ -92,8 +93,8 @@ ...@@ -92,8 +93,8 @@
} }
.modal_login_header { .modal_login_header {
background-color: #eee; background-color: #eee;
height: 50px; height: 30px;
line-height: 50px; line-height: 30px;
text-align: center; text-align: center;
font-size: 18px; font-size: 18px;
color: #333; color: #333;
...@@ -138,4 +139,9 @@ ...@@ -138,4 +139,9 @@
} }
} }
.btn-info-custom {
width: 100% !important;
}
.btn-custom-padding {
margin: 5px 5px 0px 0px;
}
// Place all the styles related to the error controller here. // Place all the styles related to the error controller here.
// They will automatically be included in application.css. // They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/ // You can use Sass (SCSS) here: http://sass-lang.com/
@media only screen and (max-width: 768px) {
.box_content_404_img {
margin: auto;
max-width: 350px;
}
.box_content_404_text {
text-align: center;
span {
font-size: 20px !important;
font-weight: 800;
color: #99a6d5;
}
}
.box_content_404_back_to_home {
text-align: center;
a {
font-size: 18px;
color: #1a2c55;
}
}
}
.box_content_404 { .box_content_404 {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
...@@ -20,6 +41,7 @@ ...@@ -20,6 +41,7 @@
.img_404 { .img_404 {
width: 100%; width: 100%;
} }
.box_content_404_text { .box_content_404_text {
text-align: center; text-align: center;
span { span {
......
// Place all the styles related to the registrations 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 users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
# frozen_string_literal: true
# Application controller
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
before_action :set_locale
def set_locale
locale = 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}
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u| u.permit(:name, :email, :cv, :password) }
devise_parameter_sanitizer.permit(:account_update) { |u| u.permit(:name, :email, :cv, :password, :current_password) }
end
end end
...@@ -14,7 +14,7 @@ class JobController < ApplicationController ...@@ -14,7 +14,7 @@ class JobController < ApplicationController
@job = Job.find(params[:id]).decorate @job = Job.find(params[:id]).decorate
cities = @job.cities.first cities = @job.cities.first
industries = @job.industries.first industries = @job.industries.first
add_breadcrumb 'Trang chủ', root_path add_breadcrumb t('controller.job.detail.home'), root_path
add_breadcrumb cities.name, jobs_path(model: 'city', slug: cities.slug) add_breadcrumb cities.name, jobs_path(model: 'city', slug: cities.slug)
add_breadcrumb industries.name, jobs_path(model: 'industry', slug: industries.slug) add_breadcrumb industries.name, jobs_path(model: 'industry', slug: industries.slug)
add_breadcrumb @job.name add_breadcrumb @job.name
......
# frozen_string_literal: true
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
confirm_sign_up_path(code: 2)
end
def after_update_path_for(resource)
my_page_path
end
end
# frozen_string_literal: true
# User controller
class UsersController < ApplicationController
before_action :authenticate_user!, only: :my_page
def confirm_sign_up
render :confirm
end
def my_page
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
...@@ -6,4 +6,15 @@ module ApplicationHelper ...@@ -6,4 +6,15 @@ module ApplicationHelper
base_title = 'VenJob' base_title = 'VenJob'
page_title.empty? ? base_title : "#{base_title} | #{page_title}" page_title.empty? ? base_title : "#{base_title} | #{page_title}"
end end
def custom_bootstrap_flash
flash_messages = []
flash.each do |type, message|
type = 'success' if type == 'notice'
type = 'error' if type == 'alert'
text = "<script>toastr.#{type}('#{message}');</script>"
flash_messages << text.html_safe if message
end
flash_messages.join("\n").html_safe
end
end end
module RegistrationsHelper
end
module UsersHelper
end
...@@ -2,9 +2,16 @@ ...@@ -2,9 +2,16 @@
# Description/Explanation of Person class # Description/Explanation of Person class
class User < ApplicationRecord class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
mount_uploader :cv, CvUploader
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :confirmable
has_many :applied_jobs has_many :applied_jobs
has_many :jobs, through: :applied_jobs has_many :jobs, through: :applied_jobs
has_many :histories has_many :histories
has_many :favorites has_many :favorites
validates_length_of :name, within: 8..200
validates_length_of :email, within: 8..200
end end
class CvUploader < CarrierWave::Uploader::Base
# Include RMagick or MiniMagick support:
# include CarrierWave::RMagick
# include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :file
# storage :fog
# Override the directory where uploaded files will be stored.
# This is a sensible default for uploaders that are meant to be mounted:
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def size_range
0..5.megabyte
end
# Provide a default URL as a default if there hasn't been a file uploaded:
# def default_url(*args)
# # For Rails 3.1+ asset pipeline compatibility:
# # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
#
# "/images/fallback/" + [version_name, "default.png"].compact.join('_')
# end
# Process files as they are uploaded:
# process scale: [200, 300]
#
# def scale(width, height)
# # do something
# end
# Create different versions of your uploaded files:
# version :thumb do
# process resize_to_fit: [50, 50]
# end
# Add a white list of extensions which are allowed to be uploaded.
# For images you might use something like this:
def extension_whitelist
%w(doc pdf xls xlsx zip)
end
# Override the filename of the uploaded files:
# Avoid using model.id or version_name here, see uploader/store.rb for details.
# def filename
# "something.jpg" if original_filename
# end
end
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<%= link_to city.name, jobs_path(model: 'city', slug: city.slug), class: 'cityjobs_link' %> <%= link_to city.name, jobs_path(model: 'city', slug: city.slug), class: 'cityjobs_link' %>
</div> </div>
<div class="box_cityjobs_count"> <div class="box_cityjobs_count">
<span><%= city.jobs.count %> Công việc</span> <span><%= "#{city.jobs.count} #{t('pages.index.job')}" %></span>
</div> </div>
</div> </div>
</div> </div>
......
<% provide(:title, 'Top thành phố') %> <% provide(:title, "#{t('pages.index.top_cities')}") %>
<%= render 'shared/scroll_top' %> <%= render 'shared/scroll_top' %>
<div class="container"> <div class="container">
<div class="box_option_location"> <div class="box_option_location">
...@@ -10,14 +10,14 @@ ...@@ -10,14 +10,14 @@
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_option_location_header"> <div class="box_option_location_header">
<span>Bạn muốn tìm việc trong hay ngoài nước?</span> <span><%= t('pages.cities.ask') %></span>
</div> </div>
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<button class="btn_option_location btn_option_location-vn">Việt Nam</button> <button class="btn_option_location btn_option_location-vn"><%= t('pages.cities.domestic') %></button>
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
<button class="btn_option_location btn_option_location-qt">Nước ngoài</button> <button class="btn_option_location btn_option_location-qt"><%= t('pages.cities.international') %></button>
</div> </div>
</div> </div>
</div> </div>
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="title_list_city title_list_city_vn"> <div class="title_list_city title_list_city_vn">
<span>Các tỉnh, thành phố thuôc Việt Nam</span> <span><%= t('pages.cities.provinces_vn') %></span>
</div> </div>
</div> </div>
<div class="container"> <div class="container">
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="title_list_city title_list_city_qt"> <div class="title_list_city title_list_city_qt">
<span>Quốc tế</span> <span><%= t('pages.cities.international') %></span>
</div> </div>
</div> </div>
<div class="container"> <div class="container">
......
<% provide(:title, 'Resend confirmation') %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center">Forgot your password?</h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-10">
<%= render "devise/shared/error_messages", resource: resource %>
</div>
</div><br>
<div class="row">
<div class="col-md-2">
<%= f.label :email %>
</div>
<div class="col-md-10">
<%= f.email_field :email, autofocus: true, autocomplete: 'email', value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-6">
<%= f.submit 'Resend confirmation instructions', class: 'btn btn-info btn-info-custom' %>
</div>
</div><br>
<% end %>
</div>
</div>
</div>
<p><%= "#{t('mailer.send_register_confirmation.wellcome')} #{@email}!" %></p>
<p><%= "#{t('mailer.send_register_confirmation.paragraph_1')}" %></p>
<p><%= link_to t('mailer.send_register_confirmation.confirm'), confirmation_url(@resource, confirmation_token: @token) %></p>
<p><%= "#{t('mailer.send_email_changed.hello')} #{@email}!"%></p>
<% if @resource.try(:unconfirmed_email?) %>
<p><%= "#{t('mailer.send_email_changed.paragraph')} #{@resource.unconfirmed_email}" %></p>
<% else %>
<p><%= "#{t('mailer.send_email_changed.paragraph')} #{ @resource.email}" %></p>
<% end %>
<p><%= "#{t('mailer.send_email_changed.hello')} #{@resource.email}!"%></p>
<p><%= t('mailer.send_password_changed.paragraph')%></p>
<p><%= "#{t('mailer.send_email_changed.hello')} #{@resource.email}!"%></p>
<p><%= t('mailer.send_reset_password_changed.paragraph_1') %></p>
<p><%= link_to t('mailer.send_reset_password_changed.btn_text_change_password'), edit_password_url(@resource, reset_password_token: @token) %></p>
<p><%= t('mailer.send_reset_password_changed.paragraph_2') %></p>
<p><%= t('mailer.send_reset_password_changed.paragraph_3') %></p>
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
<% provide(:title, 'Update password') %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center"><%= t('devise.title_change_password') %></h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= f.hidden_field :reset_password_token %>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<%= render "devise/shared/error_messages", resource: resource %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password, t('devise.new_password') %>
</div>
<div class="col-md-9">
<%= f.password_field :password, autofocus: true, autocomplete: 'new-password', class: 'form-control' %>
<% if @minimum_password_length %>
<em style="font-size: 15px; color: #666">(<%= t('devise.notice_password', minimum_password_length: @minimum_password_length) %>)</em>
<% end %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password_confirmation, t('devise.confirm_password') %><br />
</div>
<div class="col-md-9">
<%= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-6">
<%= f.submit 'Change my password', class: 'btn btn-info btn-info-custom' %>
</div>
</div><br>
<% end %>
</div>
</div>
</div>
<% provide(:title, 'Forgot password') %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center"><%= t('devise.title_forget_password') %></h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<%= render "devise/shared/error_messages", resource: resource %>
</div>
</div><br>
<div class="row">
<div class="col-md-2">
<%= f.label :email %>
</div>
<div class="col-md-10">
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-lg-6"></div>
<div class="col-lg-6">
<%= f.submit t('devise.btn_text_send_me_reset_password'), class: 'btn btn-info btn-info-custom' %>
</div>
</div><br>
<% end %>
</div>
</div>
</div>
<% provide(:title, 'Update info') %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center"><%= t('devise.title_edit_info') %></h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<%= render 'devise/shared/error_messages', resource: resource %>
</div>
<div class="col-md-3">
<%= f.label :name, t('pages.mypage.name') %>
</div>
<div class="col-md-9">
<%= f.text_field :name, autofocus: true, class: 'form-control' %>
</div>
</div><br>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="row">
<div class="col-md-3">
<%= f.label :email %>
</div>
<div class="col-md-9">
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :cv, t('pages.mypage.cv') %>
</div>
<div class="col-md-9">
<%= f.file_field :cv, autofocus: true, class: 'pppp' %>
<i style="font-size: 15px; color: #666">Current file: <%= current_user.cv.identifier %></i>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password, t('devise.pass_word') %>
</div>
<div class="col-md-9">
<%= f.password_field :password, autocomplete: 'new-password', class: 'form-control' %>
<i style="font-size: 15px; color: #666"><%= t('devise.notice_blank_password') %></i>
<% if @minimum_password_length %>
<em style="font-size: 15px; color: #666">(<%= t('devise.notice_password', minimum_password_length: @minimum_password_length)%>)</em>
<% end %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password_confirm, t('devise.confirm_password') %>
</div>
<div class="col-md-9">
<%= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :current_password, t('devise.current_password') %>
</div>
<div class="col-md-9">
<%= f.password_field :current_password, autocomplete: 'current-password', class: 'form-control' %>
<i style="font-size: 15px; color: #666"><%= t('devise.notice_current_password') %></i>
</div>
</div><br>
<div class="row">
<div class="col-md-4">
<%= link_to t('devise.back'), :back, class: 'btn btn-warning btn-info-custom' %>
</div>
<div class="col-md-4">
<%= f.submit t('devise.update'), class: 'btn btn-info btn-info-custom' %>
</div>
<% end %>
<div class="col-md-4">
<%= button_to t('devise.cancel_my_acc'), registration_path(resource_name), class: 'btn btn-danger btn-info-custom', data: { confirm: "Are you sure?" }, method: :delete %>
</div>
</div>
</div>
<hr>
</div>
</div>
<% provide(:title, "#{t('devise.title_register')}") %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center"><%= t('devise.title_register') %></h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<%= render 'devise/shared/error_messages', resource: resource %>
</div>
<div class="col-md-3">
<%= f.label :name, t('pages.mypage.name') %>
</div>
<div class="col-md-9">
<%= f.text_field :name, autofocus: true, class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :email %>
</div>
<div class="col-md-9">
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :cv, t('pages.mypage.cv') %>
</div>
<div class="col-md-9">
<%= f.file_field :cv, autofocus: true, class: 'pppp' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password, t('devise.pass_word') %>
</div>
<div class="col-md-9">
<%= f.password_field :password, autocomplete: 'new-password', class: 'form-control' %>
<% if @minimum_password_length %>
<em style="font-size: 15px;">(<%= t('devise.notice_password',minimum_password_length: @minimum_password_length) %>)</em>
<% end %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password_confirm, t('devise.confirm_password') %>
</div>
<div class="col-md-9">
<%= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-8"></div>
<div class="col-md-4">
<%= f.submit t('devise.title_register'), class: 'btn btn-info btn-info-custom' %>
</div>
</div>
<% end %>
</div>
</div>
</div>
<% provide(:title, 'Sign in') %>
<div class="container">
<div class="box_form">
<div class="row">
<div class="col-lg-12">
<h2 style="text-align: center"><%= t('devise.title_signin') %></h2><hr>
</div>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-9">
<%= render 'devise/shared/error_messages', resource: resource %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :email %>
</div>
<div class="col-md-9">
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-md-3">
<%= f.label :password, t('devise.pass_word') %>
</div>
<div class="col-md-9">
<%= f.password_field :password, autocomplete: 'new-password', class: 'form-control' %>
</div>
</div><br>
<div class="row">
<div class="col-lg-3 col-md-3">
</div>
<div class="col-lg-3">
<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me, t('devise.remember_me') %>
</div>
<% end %>
</div>
<div class="col-lg-6">
<%= f.submit t('devise.title_signin'), class: 'btn btn-info btn-info-custom' %>
<div style="text-align: center; margin-top: 10px">
<%= link_to t('devise.ask_forget_password'), new_password_path(resource_name), class: 'link_ct' %>
</div>
</div>
</div><br>
<% end %>
</div>
</div>
</div>
<div style="width: 100%; height: 5vh;"></div>
<% if resource.errors.any? %>
<div id="error_explanation">
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<%- if controller_name != 'sessions' %>
<%= link_to "Log in", new_session_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end %>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider) %><br />
<% end %>
<% end %>
<h2>Resend unlock instructions</h2>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>
<div class="actions">
<%= f.submit "Resend unlock instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
...@@ -8,14 +8,12 @@ ...@@ -8,14 +8,12 @@
</div><br> </div><br>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_content_404_text"> <div class="box_content_404_text">
<span>Có vài lỗi trong đường dẫn này<br> <span><%= "#{t('pages.errors.error_500_1')}<br>#{t('pages.errors.error_500_2')}".html_safe %></span>
Đừng lo lắng! Xin lỗi bạn vì sự bất tiện trên
</span>
</div> </div>
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_content_404_back_to_home"> <div class="box_content_404_back_to_home">
<%= link_to 'Cùng mình quay lại trang chủ nhé', root_path %> <%= link_to t('pages.errors.back_to_home'), root_path %>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
</div><br> </div><br>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_content_404_text"> <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> <span><%= t('pages.errors.error_404') %></span>
</div> </div>
</div> </div>
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_content_404_back_to_home"> <div class="box_content_404_back_to_home">
<%= link_to 'Cùng mình quay lại trang chủ nhé', root_path %> <%= link_to t('pages.errors.back_to_home'), root_path %>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<div class="col-xs-12"> <div class="col-xs-12">
<div class = "slogan"> <div class = "slogan">
<h2 class = "slogan_text"> <h2 class = "slogan_text">
NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB <%= t('pages.banner.slogan') %>
</h2> </h2>
<h5 class = "slogan_text_h5"> <h5 class = "slogan_text_h5">
NỀN TẢNG TUYỂN DỤNG NHÂN SỰ VENJOB <%= t('pages.banner.slogan') %>
</h5> </h5>
</div> </div>
</div> </div>
...@@ -18,31 +18,31 @@ ...@@ -18,31 +18,31 @@
<div class="search_scaffold"> <div class="search_scaffold">
<div class = "total_job"> <div class = "total_job">
<% if @job_count.blank? %> <% 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> <h4 class="show_total_job"><%= t('pages.banner.slogan_2') %></h4>
<% else %> <% 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> <h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %></h4>
<% end %> <% end %>
</div> </div>
<div class="filter_box"> <div class="filter_box">
<div class="search_input"> <div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="Nhập tiêu đề, công ty, địa điểm..."> <input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div> </div>
<div class="search_industries"> <div class="search_industries">
<div class="icon_list"> <div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i> <i class="fa fa-list-ul" aria-hidden="true"></i>
</div> </div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), class: 'show_list_industries' %> <%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div> </div>
<div class="search_location"> <div class="search_location">
<div class="icon_list"> <div class="icon_list">
<i class="fas fa-map-marker-alt"></i> <i class="fas fa-map-marker-alt"></i>
</div> </div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', '1'), class: 'show_list_cities' %> <%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div> </div>
<div class="search_submit"> <div class="search_submit">
<button type="submit" class="btn_search_submit"> <button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i> <i class="fas fa-search"></i>
Tìm việc <%= t('pages.banner.btn_text_search') %>
</button> </button>
</div> </div>
</div> </div>
...@@ -52,35 +52,35 @@ ...@@ -52,35 +52,35 @@
<div class="box-search-tablet"> <div class="box-search-tablet">
<div class="search_scaffold-tablet"> <div class="search_scaffold-tablet">
<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> <h4 class="show_total_job"><%= t('pages.banner.slogan_3', job_count: @job_count) %> </h4>
</div> </div>
<div class="filter_box filter_box_tablet"> <div class="filter_box filter_box_tablet">
<div class="search_input"> <div class="search_input">
<input type="search" name="" id="" class="custom_input_search" placeholder="Nhập tiêu đề, công ty, địa điểm..."> <input type="search" name="" id="" class="custom_input_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div> </div>
<div class="search_industries"> <div class="search_industries">
<div class="icon_list"> <div class="icon_list">
<i class="fa fa-list-ul" aria-hidden="true"></i> <i class="fa fa-list-ul" aria-hidden="true"></i>
</div> </div>
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), class: 'show_list_industries' %> <%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries' %>
</div> </div>
<div class="search_location"> <div class="search_location">
<div class="icon_list"> <div class="icon_list">
<i class="fas fa-map-marker-alt"></i> <i class="fas fa-map-marker-alt"></i>
</div> </div>
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', '1'), class: 'show_list_cities' %> <%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities' %>
</div> </div>
<div class="search_submit"> <div class="search_submit">
<button type="submit" class="btn_search_submit"> <button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i> <i class="fas fa-search"></i>
Tìm việc <%= t('pages.banner.btn_text_search') %>
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="box-show-total-jobs-mobile"> <div class="box-show-total-jobs-mobile">
<span>Khám phá ngay <%=@job_count%></b> việc làm tốt nhất trên VenJob</span> <span><%= t('pages.banner.slogan_3', job_count: @job_count) %> </span>
</div> </div>
<!-- Process search mobile--> <!-- Process search mobile-->
<div class="box-search-mobile"> <div class="box-search-mobile">
...@@ -88,16 +88,16 @@ ...@@ -88,16 +88,16 @@
<div class="container"> <div class="container">
<div class="row no-gutters"> <div class="row no-gutters">
<div class="col-md-12"> <div class="col-md-12">
<input type="search" name="" id="" class="custom_input_mobile_search" placeholder="Nhập tiêu đề, công ty, địa điểm..."> <input type="search" name="" id="" class="custom_input_mobile_search" placeholder="<%= t('pages.banner.search_placeholder') %>">
</div> </div>
<div class="col-sm-6 col-xs-12"> <div class="col-sm-6 col-xs-12">
<div class="search_industries_mobile"> <div class="search_industries_mobile">
<%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), class: 'show_list_industries_mobile' %> <%= select_tag 'industry', options_from_collection_for_select(@industries, 'id', 'name'), prompt: t('pages.banner.all_industries'), class: 'show_list_industries_mobile' %>
</div> </div>
</div> </div>
<div class="col-sm-6 col-xs-12"> <div class="col-sm-6 col-xs-12">
<div class="search_location_mobile"> <div class="search_location_mobile">
<%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name', '1'), class: 'show_list_cities_mobile' %> <%= select_tag 'city', options_from_collection_for_select(@cities, 'id', 'name'), prompt: t('pages.banner.all_locations'), class: 'show_list_cities_mobile' %>
</div> </div>
</div> </div>
</div> </div>
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<button type="submit" class="btn_search_submit"> <button type="submit" class="btn_search_submit">
<i class="fas fa-search"></i> <i class="fas fa-search"></i>
Tìm việc <%= t('pages.banner.btn_text_search') %>
</button> </button>
</div> </div>
</div> </div>
......
<div class="container"> <div class="container">
<div class="border_box_cities"> <div class="border_box_cities">
<div class="box_text_five_jobs box_padding_city"> <div class="box_text_five_jobs box_padding_city">
<span>Top thành phố</span> <span><%= t('pages.index.top_cities') %></span>
</div> </div>
<div class="row no-gutters"> <div class="row no-gutters">
<% @top_cities.each do |city| %> <% @top_cities.each do |city| %>
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
<%= link_to city.name, jobs_path(model: 'city', slug: city.slug),class: 'link_ct' %> <%= link_to city.name, jobs_path(model: 'city', slug: city.slug),class: 'link_ct' %>
</div> </div>
<div class="ct_jobs_count"> <div class="ct_jobs_count">
<%= link_to "#{city.jobs.count} công việc", jobs_path(model: 'city', slug: city.slug),class: 'link_ct' %> <%= link_to "#{city.jobs.count} #{t('pages.index.job')}", jobs_path(model: 'city', slug: city.slug),class: 'link_ct' %>
</div> </div>
</div> </div>
</div> </div>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_info_city"> <div class="box_info_city">
<div class="ct_name"> <div class="ct_name">
<%= link_to 'Xem Thêm', city_index_path, class: 'link_ct' %> <%= link_to t('pages.index.more'), city_index_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="container"> <div class="container">
<div class="border_box_cities"> <div class="border_box_cities">
<div class="box_text_five_jobs box_padding_city"> <div class="box_text_five_jobs box_padding_city">
<span>Top các nghành phổ biến</span> <span><%= t('pages.index.top_industries') %></span>
</div> </div>
<div class="row no-gutters"> <div class="row no-gutters">
<% @top_industries.each do |industry| %> <% @top_industries.each do |industry| %>
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<%= link_to industry.name, jobs_path(model: 'industry', slug: industry.slug), class: 'link_ct' %> <%= link_to industry.name, jobs_path(model: 'industry', slug: industry.slug), class: 'link_ct' %>
</div> </div>
<div class="ct_jobs_count"> <div class="ct_jobs_count">
<%= link_to "#{industry.jobs.count} công việc", jobs_path(model: 'industry', slug: industry.slug), class: 'link_ct' %> <%= link_to "#{industry.jobs.count} #{t('pages.index.job')}", jobs_path(model: 'industry', slug: industry.slug), class: 'link_ct' %>
</div> </div>
</div> </div>
</div> </div>
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="box_info_city"> <div class="box_info_city">
<div class="ct_name"> <div class="ct_name">
<%= link_to 'Xem Thêm', industry_index_path, class: 'link_ct' %> <%= link_to t('pages.index.more'), industry_index_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>
......
<% provide(:title ,'Trang chủ') %> <% provide(:title, "#{t('title.home')}") %>
<%= render 'home/banner_and_search' %> <%= render 'home/banner_and_search' %>
<div class="padding_index"></div> <div class="padding_index"></div>
<% unless @job_count.nil? %> <% unless @job_count.nil? %>
<div class="box_text_five_jobs"> <div class="box_text_five_jobs">
<span>Năm công việc mới nhất dành cho bạn</span> <span><%= t('pages.index.lasted_job') %></span>
</div> </div>
<%= render 'job/modal_login' %>
<%= render partial: 'job/block_info_job', collection: @lasted_jobs, as: :data %> <%= render partial: 'job/block_info_job', collection: @lasted_jobs, as: :data %>
<%= render 'box_nine_city' %> <%= render 'box_nine_city' %>
<%= render 'box_nine_industries' %> <%= render 'box_nine_industries' %>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<%= link_to industry.name, jobs_path(model: 'industry', slug: industry.slug), class: 'cityjobs_link' %> <%= link_to industry.name, jobs_path(model: 'industry', slug: industry.slug), class: 'cityjobs_link' %>
</div> </div>
<div class="box_cityjobs_count"> <div class="box_cityjobs_count">
<span><%= industry.jobs.count %> Công việc</span> <span><%= "#{industry.jobs.count} #{t('pages.index.job')}" %></span>
</div> </div>
</div> </div>
</div> </div>
<% provide(:title, 'Top nghành') %> <% provide(:title, "#{t('pages.index.top_industries')}") %>
<%= render 'shared/scroll_top' %> <%= render 'shared/scroll_top' %>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-lg-12"> <div class="col-lg-12">
<div class="title_list_city title_list_city_vn"> <div class="title_list_city title_list_city_vn">
<span>Top nghành</span> <span><%= t('pages.index.top_industries') %></span>
</div> </div>
</div> </div>
<div class="container"> <div class="container">
......
...@@ -3,9 +3,15 @@ ...@@ -3,9 +3,15 @@
<div class="col-sm-12"> <div class="col-sm-12">
<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">
<div class="link_favorite_top block_link_favorite md"> <% if user_signed_in? %>
<span><%= link_to '<i class="far fa-heart"></i>'.html_safe, '#', class: 'link_favorite' %><span> <div class="link_favorite_top block_link_favorite md">
</div> <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">
...@@ -21,24 +27,35 @@ ...@@ -21,24 +27,35 @@
<%= data.cities.map(&:name).join(' | ') %> <%= data.cities.map(&:name).join(' | ') %>
</h5> </h5>
</div> </div>
<h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp; Lương: <%= data.salary %></h5> <h5 class="box_info_salary"><i class="fas fa-dollar-sign"></i>&nbsp;<%= "#{t('pages.index.salary')}: #{data.salary}" %></h5>
<div class="coc"> <div class="coc">
<h5 class="box_info_des"><%= strip_tags(data.description) %></h5> <h5 class="box_info_des"><%= strip_tags(data.description) %></h5>
</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_link_favotite"> <% if user_signed_in? %>
<div class="block_link_favorite lg"> <div class="box_link_favotite">
<span><i class="far fa-heart"></i> <%= link_to 'Yêu thích', '#', class: 'link_favorite' %><span> <div class="block_link_favorite lg">
<span><i class="far fa-heart"></i> <%= link_to t('pages.index.btn_text_favorite'), '#', 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> </div>
<div class="block_link_favorite md"> <% else %>
<span><%= link_to '<i class="far fa-heart"></i>'.html_safe, '#', class: 'link_favorite' %><span> <div class="box_link_favotite">
<div class="block_click_favorite lg">
<span><i class="far fa-heart"></i> <%= t('pages.index.btn_text_favorite') %><span>
</div>
<div class="block_click_favorite md">
<span><i class="far fa-heart"></i><span>
</div>
</div> </div>
</div> <% end %>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
\ No newline at end of file
<div class="overlay_login"> <div class="overlay_login">
<div class="modal_login"> <div class="modal_login">
<div class="modal_login_header"> <div class="modal_login_header">
<span>VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY</span> <span><%= t('devise.notification') %></span>
<span class="icon_close_modal_login"> <span class="icon_close_modal_login">
<i class="fas fa-times"></i> <i class="fas fa-times"></i>
</span> </span>
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
<div class="row"> <div class="row">
<div class="col-lg 12"> <div class="col-lg 12">
<div class="modal_login_notice_text"> <div class="modal_login_notice_text">
<span>ĐĂNG NHẬP</span> <span><%= t('pages.confirm.modal_login').downcase.capitalize %></span><br>
<span><b><%= link_to t('devise.title_signin'), new_user_session_path, class: 'link_ct' %></b></span>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -24,13 +24,13 @@ ...@@ -24,13 +24,13 @@
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<div class="btn_apply_job"> <div class="btn_apply_job">
<%= link_to 'Nộp CV ngay', '#', class: 'btn btn-apply_job' %> <%= link_to t('pages.detail.btr_text_submit_cv'), '#', class: 'btn btn-apply_job' %>
</div> </div>
</div> </div>
<div class="col-lg-12 col-md-12"> <div class="col-lg-12 col-md-12">
<div class="box_detail_jobs"> <div class="box_detail_jobs">
<div class="box_detail_jobs_location"> <div class="box_detail_jobs_location">
<span><i class="fas fa-map-marker-alt"></i> Địa điểm làm việc: </span> <span><i class="fas fa-map-marker-alt"></i><%= t('pages.detail.work_location') %></span>
<% @job.cities.each do |x| %> <% @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 %> <% end %>
...@@ -40,27 +40,27 @@ ...@@ -40,27 +40,27 @@
<div class="row"> <div class="row">
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
<div class="detail_info"> <div class="detail_info">
<span><i class="fab fa-linode"></i> Lương: <%= @job.salary %></span> <span><i class="fab fa-linode"></i> <%= "#{t('pages.index.salary')}: #{@job.salary}" %></span>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
<div class="detail_info"> <div class="detail_info">
<span><i class="fab fa-linode"></i> Ngày đăng tin: <%= @job.posted_at %></span> <span><i class="fab fa-linode"></i> <%= "#{t('pages.detail.posted_at')}: #{@job.posted_at}" %></span>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
<div class="detail_info"> <div class="detail_info">
<span><i class="fab fa-linode"></i> Ngày hết hạn: <%= @job.expiration_date.present? ? @job.expired_at : 'đang cập nhật' %></span> <span><i class="fab fa-linode"></i> <%= "#{t('pages.detail.expiration_date')}: #{@job.expiration_date.present? ? @job.expired_at : 'đang cập nhật'}" %></span>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
<div class="detail_info"> <div class="detail_info">
<span><i class="fab fa-linode"></i> Kinh nghiệm: <%= @job.experience %></span> <span><i class="fab fa-linode"></i> <%= "#{t('pages.detail.experience')}: #{@job.experience}" %></span>
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
<div class="detail_info"> <div class="detail_info">
<span><i class="fab fa-linode"></i> Cấp bậc: <%= @job.level %></span> <span><i class="fab fa-linode"></i> <%= "#{t('pages.detail.level')}: #{@job.level}" %></span>
</div> </div>
</div> </div>
</div> </div>
...@@ -80,12 +80,12 @@ ...@@ -80,12 +80,12 @@
<div class="row"> <div class="row">
<div class="col-lg-6 col-md-6"> <div class="col-lg-6 col-md-6">
<div class="btn_apply_job"> <div class="btn_apply_job">
<%= link_to 'Nộp CV ngay', '#', class: 'btn btn-apply_job' %> <%= link_to t('pages.detail.btr_text_submit_cv'), '#', class: 'btn btn-apply_job' %>
</div> </div>
</div> </div>
<div class="col-lg-6 col-md-6"> <div class="col-lg-6 col-md-6">
<div class="btn_apply_job"> <div class="btn_apply_job">
<%= link_to 'Yêu thích', '#', class: 'btn btn-apply_job_favorite' %> <%= link_to t('pages.index.btn_text_favorite'), '#', class: 'btn btn-apply_job_favorite' %>
</div> </div>
</div> </div>
</div> </div>
......
<% provide(:title ,'Kết quả tìm kiếm') %> <% provide(:title ,"#{t('pages.detail.br_title')}") %>
<%= render 'home/banner_and_search' %> <%= render 'home/banner_and_search' %>
<div class="padding_index"></div> <div class="padding_index"></div>
<div class="container"> <div class="container">
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
<span class="breadcrumb-item active"> <span class="breadcrumb-item active">
<% if @data.total_count > 0 %> <% if @data.total_count > 0 %>
<div style="word-wrap: break-word;"> <div style="word-wrap: break-word;">
<span>&nbsp;<b><%= @data.total_count %></b>&nbsp;kết quả phù hợp với từ khóa&nbsp;</span><b><%= @keyword %></b>&nbsp; <%= t('pages.result.result_find', job: @data.total_count, key: @keyword).html_safe %>
</div> </div>
<% else %> <% else %>
Không có kết quả phù hợp với từ khóa&nbsp;<b><%= @keyword %></b> <%= t('pages.result.no_result_find', key: @keyword).html_safe %>
<% end %> <% end %>
</span> </span>
</div> </div>
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
</div> </div>
</div> </div>
</div> </div>
<%= render 'job/modal_login' %>
<%= render partial: 'block_info_job', collection: @data, as: :data %> <%= render partial: 'block_info_job', collection: @data, as: :data %>
<div class="container"> <div class="container">
<div class="row"> <div class="row">
......
...@@ -10,16 +10,25 @@ ...@@ -10,16 +10,25 @@
<div class="header_top_menu_right"> <div class="header_top_menu_right">
<ul class="list_menu_header_right"> <ul class="list_menu_header_right">
<li class="list_item_menu_header_right"> <li class="list_item_menu_header_right">
<%= link_to 'Yêu thích', '#', class: 'link_item_menu_header_right' %> <%= link_to t('pages.index.favorite'), '#', class: 'link_item_menu_header_right' %>
</li> </li>
<li class="list_item_menu_header_right"> <li class="list_item_menu_header_right">
<%= link_to 'Lịch sử', '#', class: 'link_item_menu_header_right' %> <%= link_to t('pages.index.history'), '#', class: 'link_item_menu_header_right' %>
</li> </li>
<li class="list_item_menu_header_right"> <li class="list_item_menu_header_right">
<%= link_to 'Đăng nhập', '#', class: 'link_item_menu_header_right' %> <%= link_to_if(user_signed_in?, t('pages.index.mypage'), my_page_path, class: 'link_item_menu_header_right') do
link_to t('pages.index.signin'), new_user_session_path, class: 'link_item_menu_header_right'
end %>
</li> </li>
<li class="list_item_menu_header_right"> <li class="list_item_menu_header_right">
<%= link_to 'Đăng ký', '#', class: 'link_item_menu_header_right' %> <%= link_to_if(user_signed_in?, t('pages.index.signout'), destroy_user_session_path, method: :delete, class: 'link_item_menu_header_right') do
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> </li>
</ul> </ul>
</div> </div>
...@@ -30,20 +39,31 @@ ...@@ -30,20 +39,31 @@
<div class = "menu_mobile_vertical"> <div class = "menu_mobile_vertical">
<ul class = "list_menu_mobile_vertical"> <ul class = "list_menu_mobile_vertical">
<li class = "item_menu_mobile_vertical"> <li class = "item_menu_mobile_vertical">
<%= link_to 'Yêu thích', '#', class: 'link_item_menu_mobile' %> <%= link_to t('pages.index.favorite'), '#', class: 'link_item_menu_mobile' %>
</li> </li>
<li class = "item_menu_mobile_vertical"> <li class = "item_menu_mobile_vertical">
<%= link_to 'Lịch sử', '#', class: 'link_item_menu_mobile' %> <%= link_to t('pages.index.history'), '#', class: 'link_item_menu_mobile' %>
</li> </li>
<li class = "item_menu_mobile_vertical"> <li class="item_menu_mobile_vertical">
<%= link_to 'Đăng nhập', '#', class: 'link_item_menu_mobile' %> <%= link_to_if(user_signed_in?, t('pages.index.mypage'), my_page_path, class: 'link_item_menu_mobile') do
link_to t('pages.index.signin'), new_user_session_path, class: 'link_item_menu_mobile'
end %>
</li>
<li class="item_menu_mobile_vertical">
<%= link_to_if(user_signed_in?, t('pages.index.signout'), destroy_user_session_path, method: :delete, class: 'link_item_menu_mobile') do
link_to t('pages.index.register'), new_user_registration_path, class: 'link_item_menu_mobile'
end %>
</li><hr style="width: 60%; background-color: #999;">
<li class="item_menu_mobile_vertical">
<span class="link_item_menu_mobile custom"><%= t('pages.index.language') %></span>
</li> </li>
<li class = "item_menu_mobile_vertical"> <li class="item_menu_mobile_vertical">
<%= link_to 'Đăng ký', '#', class: 'link_item_menu_mobile' %> <%= 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' %>
</li> </li>
</ul> </ul>
</div> </div>
<div> <div>
</div> </div>
</div> </div>
</header> </header>
\ No newline at end of file
...@@ -14,7 +14,9 @@ ...@@ -14,7 +14,9 @@
<body> <body>
<div class = "app"> <div class = "app">
<%= render 'layouts/header' %> <%= render 'layouts/header' %>
<%= render 'layouts/padding' %> <%= custom_bootstrap_flash %>
<% flash.discard %>
<%= render 'layouts/padding' %>
<%= yield %> <%= yield %>
<%= render 'layouts/footer' %> <%= render 'layouts/footer' %>
</div> </div>
......
<div class="container">
<div class="box_form">
<h3>VENJOB</h3>
<p>
<%= t('mailer.register_confirmation.paragraph_1') %>
<%= t('mailer.register_confirmation.paragraph_2') %><br>
<%= t('mailer.register_confirmation.paragraph_3') %>
</p>
<div class="list_email_app">
<ul>
<li>
<span><%= t('pages.mypage.you_are_using') %></span>
</li>
<li>
<a href="https://mail.google.com/" target="_blank"><i class="fas fa-inbox"></i> Gmail</a>
</li>
<li>
<a href="https://login.yahoo.com/" target="_blank"><i class="fab fa-yahoo"></i> Yahoo</a>
</li>
<li>
<a href="https://outlook.live.com/" target="_blank"><i class="fab fa-windows"></i> Outlook</a>
</li>
</ul>
</div>
</div>
</div>
<div style="width: 100%; height: 15vh;"></div>
<div class="container">
<div class="box_my_page">
<div class="row">
<div class="col-lg-12">
<div class="box_my_page_header">
<h4><%= t('pages.mypage.title') %></h4>
</div>
</div>
<div class="box_my_page_content">
<hr>
<div class="row">
<div class="col-lg-12">
<span><%= "#{t('pages.mypage.email')}: #{current_user.email}" %></span>
</div>
<div class="col-lg-12">
<span><%= "#{t('pages.mypage.name')}: #{current_user.name}" %></span>
</div>
<div class="col-lg-12">
<% if current_user.cv.identifier %>
CV: <%= link_to current_user.cv.identifier, current_user.cv.url, target: '_blank', class: 'link_ct pdf' %>
<%= link_to '<i class="fas fa-download"></i>'.html_safe, current_user.cv.url, download: current_user.cv.identifier %>
<% else %>
CV: <span class="link_ct"><%= t('pages.mypage.nofile') %></span>
<% end %>
</div>
<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'%>
</div>
</div>
<hr>
</div>
</div>
</div>
</div>
<div style="width: 100%; height: 55vh"></div>
...@@ -13,6 +13,10 @@ module Venjob ...@@ -13,6 +13,10 @@ module Venjob
config.exceptions_app = self.routes config.exceptions_app = self.routes
config.autoload_paths << Rails.root.join('lib/service') config.autoload_paths << Rails.root.join('lib/service')
config.autoload_paths << Rails.root.join('lib/src') config.autoload_paths << Rails.root.join('lib/src')
# i18n
config.i18n.available_locales = [:en, :vi]
config.i18n.default_locale = :en
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
# 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
......
Rails.application.configure do Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb. # Settings specified here will take precedence over those in config/application.rb.
config.action_mailer.default_url_options = { host: 'localhost', port: 1234 }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
user_name: ENV['SENDMAIL_USERNAME'],
password: ENV['SENDMAIL_PASSWORD'],
domain: ENV['MAIL_HOST'],
address: 'smtp.gmail.com',
port: '587',
authentication: :plain,
enable_starttls_auto: true
}
# In the development environment your application's code is reloaded on # In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development # every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes. # since you don't have to restart the web server when you make code changes.
......
Rails.application.configure do Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb. # Settings specified here will take precedence over those in config/application.rb.
config.action_mailer.default_url_options = { host: 'hungnt-venjob.herokuapp.com' }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
user_name: ENV['SENDMAIL_USERNAME'],
password: ENV['SENDMAIL_PASSWORD'],
domain: 'hungnt-venjob.herokuapp.com',
address: 'smtp.gmail.com',
port: '587',
authentication: :plain,
enable_starttls_auto: true
}
# Code is not reloaded between requests. # Code is not reloaded between requests.
config.cache_classes = true config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and # Eager load code on boot. This eager loads most of Rails and
......
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
en:
devise:
confirmations:
confirmed: "Your email address has been successfully confirmed."
send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes."
failure:
already_authenticated: "You are already signed in."
inactive: "Your account is not activated yet."
invalid: "Invalid %{authentication_keys} or password."
locked: "Your account is locked."
last_attempt: "You have one more attempt before your account is locked."
not_found_in_database: "Invalid %{authentication_keys} or password."
timeout: "Your session expired. Please sign in again to continue."
unauthenticated: "You need to sign in or sign up before continuing."
unconfirmed: "You have to confirm your email address before continuing."
mailer:
confirmation_instructions:
subject: "Confirmation instructions"
reset_password_instructions:
subject: "Reset password instructions"
unlock_instructions:
subject: "Unlock instructions"
email_changed:
subject: "Email Changed"
password_change:
subject: "Password Changed"
omniauth_callbacks:
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
success: "Successfully authenticated from %{kind} account."
passwords:
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
updated: "Your password has been changed successfully. You are now signed in."
updated_not_active: "Your password has been changed successfully."
registrations:
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
signed_up: "Welcome! You have signed up successfully."
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirmation link to confirm your new email address."
updated: "Your account has been updated successfully."
updated_but_not_signed_in: "Your account has been updated successfully, but since your password was changed, you need to sign in again"
sessions:
signed_in: "Signed in successfully."
signed_out: "Signed out successfully."
already_signed_out: "Signed out successfully."
unlocks:
send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
errors:
messages:
already_confirmed: "was already confirmed, please try signing in"
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
expired: "has expired, please request a new one"
not_found: "not found"
not_locked: "was not locked"
not_saved:
one: "1 error prohibited this %{resource} from being saved:"
other: "%{count} errors prohibited this %{resource} from being saved:"
# Additional translations at https://github.com/heartcombo/devise/wiki/I18n
vi:
devise:
confirmations:
confirmed: 'Địa chỉ email của bạn đã được xác nhận thành công.'
send_instructions: 'Bạn sẽ nhận được một email hướng dẫn về cách xác nhận địa chỉ email của bạn trong vài phút.'
send_paranoid_instructions: 'Nếu địa chỉ email của bạn tồn tại trong sở dữ liệu của chúng tôi, bạn sẽ nhận được email hướng dẫn cách xác nhận địa chỉ email của bạn sau vài phút.'
failure:
already_authenticated: 'Bạn đã đăng nhập.'
inactive: 'Tài khoản của bạn chưa được kich hoạt.'
invalid: "%{authentication_keys} hoặc mật khẩu không hợp lệ."
locked: 'Tài khoản của bạn bị khóa.'
last_attempt: 'Bạn còn một lần thử nữa trước khi tài khoản của bạn bị khóa.'
not_found_in_database: "%{authentication_keys} hoặc mật khẩu không hợp lệ."
timeout: 'Phiên của bạn đã hết hạn. Vui lòng đăng nhập lại để tiếp tục'
unauthenticated: 'Bạn cần đăng nhập hoặc đăng trước khi tiếp tục.'
unconfirmed: 'Bạn phải xác nhận địa chỉ email của mình trước khi tiếp tục.'
mailer:
confirmation_instructions:
subject: 'Xác nhận hướng dẫn'
reset_password_instructions:
subject: 'Hướng dẫn đặt lại mật khẩu'
unlock_instructions:
subject: 'Hướng dẫn mở khóa'
email_changed:
subject: 'Email đã thay đổi'
password_change:
subject: 'Mật khẩu đã được thay đổi'
omniauth_callbacks:
failure: "Không thể xác thực bạn từ %{kind} bởi \"%{reason}\"."
success: "Đã xác thực thành công từ %{kind} tài khoản."
passwords:
no_token: 'Bạn không thể truy cập trang này nếu không nhận được email đặt lại mật khẩu. Nếu bạn đến từ email đặt lại mật khẩu, hãy đảm bảo rằng bạn đã sử dụng URL đầy đủ được cung cấp.'
send_instructions: 'Bạn sẽ nhận được một email hướng dẫn về cách đặt lại mật khẩu của mình sau vài phút.'
send_paranoid_instructions: 'Nếu địa chỉ email của bạn tồn tại trong sở dữ liệu của chúng tôi, bạn sẽ nhận được liên kết khôi phục mật khẩu tại địa chỉ email của bạn sau vài phút.'
updated: 'Mật khẩu của bạn đã được thay đổi thành công. Bây giờ bạn đã đăng nhập.'
updated_not_active: 'Mật khẩu của bạn đã được thay đổi thành công.'
registrations:
destroyed: 'Tạm biệt! Tài khoản của bạn đã được hủy thành công. Mong rằng chúng tôi sẽ sớm gặp lại bạn.'
signed_up: 'Chào mừng! Bạn đã đăng thành công.'
signed_up_but_inactive: 'Bạn đã đăng thành công. Tuy nhiên, chúng tôi không thể đăng nhập cho bạn tài khoản của bạn chưa được kích hoạt.'
signed_up_but_locked: 'Bạn đã đăng thành công. Tuy nhiên, chúng tôi không thể đăng nhập cho bạn tài khoản của bạn bị khóa.'
signed_up_but_unconfirmed: 'Một tin nhắn với một liên kết xác nhận đã được gửi đến địa chỉ email của bạn. Vui lòng nhấp vào liên kết để kích hoạt tài khoản của bạn.'
update_needs_confirmation: 'Bạn đã cập nhật tài khoản của mình thành công, nhưng chúng tôi cần xác minh địa chỉ email mới của bạn. Vui lòng kiểm tra email của bạn nhấp vào liên kết xác nhận để xác nhận địa chỉ email mới của bạn.'
updated: 'Tài khoản của bạn đã được cập nhật thành công.'
updated_but_not_signed_in: 'Tài khoản của bạn đã được cập nhật thành công, nhưng mật khẩu của bạn đã được thay đổi, bạn cần đăng nhập lại'
sessions:
signed_in: 'Đã đăng nhập thành công.'
signed_out: 'Đã đăng xuất thành công.'
already_signed_out: 'Đăng xuất thành công'
unlocks:
send_instructions: 'Bạn sẽ nhận được một email hướng dẫn về cách mở khóa tài khoản của mình sau vài phút.'
send_paranoid_instructions: 'Nếu tài khoản của bạn tồn tại, bạn sẽ nhận được email hướng dẫn cách mở khóa sau vài phút.'
unlocked: 'Tài khoản của bạn đã được mở khóa thành công. Vui lòng đăng nhập để tiếp tục.'
errors:
messages:
already_confirmed: 'Tài khoản cuản bạn đã được xác nhận, vui lòng thử đăng nhập'
confirmation_period_expired: "cần được xác nhận trong %{period}, vui lòng tạo yêu cầu mới"
expired: "đã hết hạn, vui lòng tạo yêu cầu mới"
not_found: "không tìm thấy"
not_locked: "không bị khóa"
not_saved:
one: "1 lỗi được phát hiện %{resource} trước khi lưu:"
other: "%{count} lỗi được phát hiện %{resource} trước khi lưu:"
# Files in the config/locales directory are used for internationalization
# and are automatically loaded by Rails. If you want to use locales other
# than English, add the necessary files in this directory.
#
# To use the locales, use `I18n.t`:
#
# I18n.t 'hello'
#
# In views, this is aliased to just `t`:
#
# <%= t('hello') %>
#
# To use a different locale, set it with `I18n.locale`:
#
# I18n.locale = :es
#
# This would use the information in config/locales/es.yml.
#
# The following keys must be escaped otherwise they will not be retrieved by
# the default I18n backend:
#
# true, false, on, off, yes, no
#
# Instead, surround them with single quotes.
#
# en:
# 'true': 'foo'
#
# To learn more, please read the Rails Internationalization guide
# available at http://guides.rubyonrails.org/i18n.html.
en: en:
hello: "Hello world" title:
home: 'Home'
pages:
index:
favorite: 'Favorite'
history: 'History'
signin: 'Sign in'
register: 'Register'
mypage: 'My page'#{t('pages.index.job')}
signout: 'Sign out'
language: 'Language'
lasted_job: 'Five new job for you'
top_industries: 'Top Industries'
top_cities: 'Top Cities'
job: 'jobs'
more: 'More'
btn_text_favorite: 'Favorite'
salary: ' Salary'
banner:
slogan: 'VENJOB HUMAN RESOURCE PLATFORM'
slogan_2: 'Instantly discover the best jobs on VenJob'
slogan_3: 'Instantly discover %{job_count} the best jobs on VenJob'
search_placeholder: 'Input title, companies, locations...'
btn_text_search: 'Find Job'
all_industries: 'All industries'
all_locations: 'All locations'
confirm:
modal_login: 'PLEASE SIGN IN TO EXECUTE THIS FUNCTION'
result:
result_find: 'There are <b>%{job}</b> results matching keyword <b>%{key}</b>'
no_result_find: 'No results match the keyword <b>%{key}</b>'
detail:
br_title: 'Result'
btr_text_submit_cv: 'Apply Now'
work_location: ' Work locations: '
posted_at: ' Posted at'
expiration_date: ' Expiration date'
experience: ' Experience'
level: ' Level'
cities:
ask: 'Do you want to find a job at Viet Nam or oversea?'
domestic: 'Viet Nam'
international: 'International'
provinces_vn: 'Provinces and cities of Vietnam'
mypage:
title: 'My page'
email: 'Email'
name: 'Name'
cv: 'Curriculum Vitae'
update: 'Update'
myjob: 'My jobs'
nofile: 'Please upload your cv'
you_are_using: "You're using:"
errors:
back_to_home: "Let's go back to the homepage"
error_500_1: 'There are some errors in this path'
error_500_2: 'Do not worry! Sorry for the inconvenience!'
error_404: 'We cannot find the page you requested!'
controller:
job:
detail:
home: 'Home'
mailer:
register_confirmation:
paragraph_1: 'Thank you for register our service, an confirmation email with registration link has been sent to your email'
paragraph_2: 'Please check your email within 24 hours. Please note that the registration link is only valid for 24 hours'
paragraph_3: 'Over that period, you will have to register your emai again.'
send_register_confirmation:
wellcome: 'Welcome'
paragraph_1: "By clicking on the following link, you are confirming your email address and agreeing to VeNJOB's Terms of Service."
confirm: 'Confirm my account'
send_email_changed:
hello: 'Hello'
paragraph: "We're contacting you to notify you that your email is being changed to"
send_reset_password_changed:
btn_text_change_password: 'Change my password'
paragraph_1: 'Someone has requested a link to change your password. You can do this through the link below.'
paragraph_2: "If you didn't request this, please ignore this email."
paragraph_3: "Your password won't change until you access the link above and create a new one."
send_password_changed:
paragraph: "We're contacting you to notify you that your password has been changed."
devise:
notification: 'NOTIFICATION'
title_signin: 'Sign in'
title_register: 'Register'
title_edit_info: 'Edit my info'
title_forget_password: 'Forgot your password?'
title_change_password: 'Change your password'
pass_word: 'Password'
new_password: 'New password'
confirm_password: 'Confirm new password'
current_password: 'Current password'
notice_blank_password: "Leave blank if you don't want to change it "
notice_password: 'Password have a minimum of %{minimum_password_length} characters'
notice_current_password: 'We need your current password to confirm your changes'
btn_text_send_me_reset_password: 'Send me reset password instructions'
btn_text_change_password: 'Change my password'
back: 'Back'
update: 'Update'
cancel_my_acc: 'Cancel my account'
remember_me: 'Remember Me'
ask_forget_password: 'Forgot your password?'
vi:
title:
home: 'Trang chủ'
pages:
index:
favorite: 'Yêu thích'
history: 'Lịch sử'
signin: 'Đăng nhập'
register: 'Đăng ký'
mypage: 'Trang nhân'
signout: 'Đăng xuất'
language: 'Ngôn ngữ'
lasted_job: 'Năm công việc mới nhất dành cho bạn'
top_industries: 'Nhóm nghành đang phổ biến'
top_cities: 'Top thành phố'
job: 'công việc'
more: 'Xem thêm'
btn_text_favorite: 'Yêu thích'
salary: ' Lương'
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'
slogan_3: "Khám phá ngay %{job_count} việc làm tốt nhất trên VenJob"
search_placeholder: 'Nhập tiêu đề, công ty, địa điểm...'
btn_text_search: 'Tìm việc'
all_industries: 'Tất cả nghành nghề'
all_locations: 'Tất cả đỉa điểm'
confirm:
modal_login: 'VUI LÒNG ĐĂNG NHẬP ĐỂ THỰC HIỆN CHỨC NĂNG NÀY'
result:
result_find: ' <b>%{job}</b> kết quả phù hợp với từ khóa <b>%{key}</b>'
no_result_find: 'Không kết quả phù hợp với từ khóa <b>%{key}</b>'
detail:
br_title: 'Kết quả tìm kiếm'
btr_text_submit_cv: 'Nộp CV ngay'
work_location: ' Địa điểm làm việc: '
posted_at: ' Ngày đăng tin'
expiration_date: ' Ngày hết hạn'
experience: ' Kinh nghiệm'
level: ' Cấp bậc'
cities:
ask: 'Bạn muốn tìm việc trong hay ngoài nước?'
domestic: 'Việt Nam'
international: 'Nước ngoài'
provinces_vn: 'Các tỉnh, thành phố thuôc Việt Nam'
mypage:
title: 'Trang nhân'
email: 'Email'
name: 'Họ tên'
cv: ' yếu lịch'
update: 'Cập nhật'
myjob: 'Công việc của tôi'
nofile: 'Vui lòng tải lên cv của bạn'
you_are_using: 'Bạn đang sử dụng:'
errors:
back_to_home: 'Cùng mình quay lại trang chủ nhé'
error_500_1: ' vài lỗi trong đường dẫn này'
error_500_2: 'Đừng lo lắng! Xin lỗi bạn sự bất tiện trên!'
error_404: 'Chúng tôi không tìm thấy trang bạn bạn yêu cầu!'
controller:
job:
detail:
home: 'Trang chủ'
mailer:
register_confirmation:
paragraph_1: 'Cảm ơn bạn đã đăng dịch vụ của chúng tôi, một email xác nhận với liên kết đăng đã được gửi đến email của bạn.'
paragraph_2: 'Vui lòng kiểm tra email của bạn trong vòng 24 giờ. Xin lưu ý rằng liên kết đăng chỉ hiệu lực trong 24 giờ.'
paragraph_3: 'Sau 24h nếu bạn không xác nhận, bạn sẽ phải đăng lại email của mình.'
send_register_confirmation:
wellcome: 'Chào mừng bạn '
paragraph_1: "Bằng cách nhấp vào liên kết sau, bạn đang xác nhận địa chỉ email của mình đồng ý với Điều khoản dịch vụ của VeNJOB."
confirm: 'Xác nhận tài khoản'
send_email_changed:
hello: 'Xin chào'
paragraph: 'Chúng tôi đang liên hệ với bạn để thông báo rằng email của bạn đang được thay đổi thành'
send_reset_password_changed:
btn_text_change_password: 'Thay đổi mật khẩu của tôi'
paragraph_1: 'Ai đó đã yêu cầu một liên kết để thay đổi mật khẩu của bạn. Bạn thể làm điều này thông qua liên kết dưới đây.'
paragraph_2: 'Nếu bạn không yêu cầu, vui lòng bỏ qua email này.'
paragraph_3: 'Mật khẩu của bạn sẽ không thay đổi cho đến khi bạn truy cập vào liên kết trên tạo một mật khẩu mới.'
send_password_changed:
paragraph: 'Chúng tôi đang liên hệ với bạn để thông báo rằng mật khẩu của bạn đã được thay đổi.'
devise:
notification: 'THÔNG BÁO'
title_signin: 'Đăng nhập'
title_register: 'Đăng ký'
title_edit_info: 'Cập nhật thông tin tài khoản'
title_forget_password: 'Quên mật khẩu?'
title_change_password: 'Thay đổi mật khẩu'
pass_word: 'Mật khẩu'
new_password: 'Mật khẩu mới'
confirm_password: 'Xác nhận lại mật khẩu'
current_password: 'Mật khẩu hiện tại'
notice_blank_password: 'Để trống nếu bạn không muốn thay đổi nó'
notice_password: 'Mật khẩu tối thiểu %{minimum_password_length} tự'
notice_current_password: 'Chúng tôi cần mật khẩu hiện tại của bạn để xác nhận các thay đổi của bạn'
btn_text_send_me_reset_password: 'Gửi cho tôi hướng dẫn đặt lại mật khẩu'
btn_text_change_password: 'Thay đổi mật khẩu'
back: 'Quay lại'
update: 'Cập nhật'
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?'
\ No newline at end of file
# frozen_string_literal: true # frozen_string_literal: true
Rails.application.routes.draw do Rails.application.routes.draw do
root 'home#index' scope '(:locale)', locale: /en|vi/ do
get 'industries', to: 'industry#index', as: :industry_index devise_for :users, controllers: {registrations: 'registrations'}
get 'cities', to: 'city#index', as: :city_index
# Details job root 'home#index'
get 'detail/:id', to: 'job#detail', as: :detail_job
# Search get 'register/:code', to: 'users#confirm_sign_up', as: :confirm_sign_up
get 'jobs/:model/:slug', to: 'job#index', as: :jobs get 'industries', to: 'industry#index', as: :industry_index
get 'cities', to: 'city#index', as: :city_index
# Rails error # Details job
match '/404', to: 'error#page_not_found', via: :all get 'detail/:id', to: 'job#detail', as: :detail_job
match '/500', to: 'error#internal_server_error', via: :all # Search
get 'jobs/:model/:slug', to: 'job#index', as: :jobs
# My page
get 'my', to: 'users#my_page', as: :my_page
# Rails error
match '/404', to: 'error#page_not_found', via: :all
match '/500', to: 'error#internal_server_error', via: :all
end
end end
# frozen_string_literal: true
class AddDeviseToUsers < ActiveRecord::Migration[5.2]
remove_column :users, :password_digest, :string
def self.up
change_table :users do |t|
## Database authenticatable
t.string :encrypted_password, null: false, default: ''
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
# t.integer :sign_in_count, default: 0, null: false
# t.datetime :current_sign_in_at
# t.datetime :last_sign_in_at
# t.string :current_sign_in_ip
# t.string :last_sign_in_ip
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
# Uncomment below if timestamps were not included in your original model.
# t.timestamps null: false
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
def self.down
# By default, we don't want to make any assumption about how to roll back a migration when your
# model already existed. Please edit below which fields you would like to remove in this migration.
raise ActiveRecord::IrreversibleMigration
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_08_05_075807) do ActiveRecord::Schema.define(version: 2020_08_11_005812) do
create_table "applied_jobs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t| create_table "applied_jobs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
t.bigint "user_id" t.bigint "user_id"
...@@ -96,11 +96,20 @@ ActiveRecord::Schema.define(version: 2020_08_05_075807) do ...@@ -96,11 +96,20 @@ ActiveRecord::Schema.define(version: 2020_08_05_075807) do
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t| create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
t.string "email" t.string "email"
t.string "name" t.string "name"
t.string "password_digest"
t.text "cv" t.text "cv"
t.boolean "admin", default: false t.boolean "admin", default: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
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 end
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 ErrorControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end
require 'test_helper'
class HomeControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get home_index_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 "the truth" do
# assert true
# end
end
require 'test_helper'
class JobDecoratorTest < Draper::TestCase
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