Commit e1a5c262 by Mai Hoang Thai Ha

Merge branch 'top_view/suggest' into 'master'

Top view/suggest

See merge request !21
parents 9f9afa19 eabd44f2
...@@ -65,6 +65,8 @@ gem 'nokogiri', '~> 1.11', '>= 1.11.7' ...@@ -65,6 +65,8 @@ gem 'nokogiri', '~> 1.11', '>= 1.11.7'
gem 'httparty', '~> 0.18.1' gem 'httparty', '~> 0.18.1'
gem 'active_storage_validations', '~> 0.9.5' gem 'active_storage_validations', '~> 0.9.5'
gem 'devise', '~> 4.8' gem 'devise', '~> 4.8'
gem 'jquery-rails', '~> 4.4'
gem 'rsolr', '~> 2.3' gem 'rsolr', '~> 2.3'
gem 'rsolr-ext', '~> 1.0', '>= 1.0.3' gem 'rsolr-ext', '~> 1.0', '>= 1.0.3'
gem 'font-awesome-rails', '~> 4.7', '>= 4.7.0.7'
gem 'bootstrap', '~> 4.4.1'
gem 'jquery-rails', '~> 4.4'
...@@ -82,24 +82,31 @@ GEM ...@@ -82,24 +82,31 @@ GEM
addressable (2.8.0) addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2) ast (2.4.2)
autoprefixer-rails (10.3.3.0)
execjs (~> 2)
bcrypt (3.1.16) bcrypt (3.1.16)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.9.1) bootsnap (1.9.1)
msgpack (~> 1.0) msgpack (~> 1.0)
bootstrap (4.4.1)
autoprefixer-rails (>= 9.1.0)
popper_js (>= 1.14.3, < 2)
sassc-rails (>= 2.0.0)
builder (3.2.4) builder (3.2.4)
bullet (6.1.5) bullet (6.1.5)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
uniform_notifier (~> 1.11) uniform_notifier (~> 1.11)
byebug (11.1.3) byebug (11.1.3)
capybara (3.35.3) capybara (3.36.0)
addressable addressable
matrix
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (~> 1.8) nokogiri (~> 1.8)
rack (>= 1.6.0) rack (>= 1.6.0)
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0) regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2) xpath (~> 3.2)
childprocess (3.0.0) childprocess (4.1.0)
coderay (1.1.3) coderay (1.1.3)
concurrent-ruby (1.1.9) concurrent-ruby (1.1.9)
crass (1.0.6) crass (1.0.6)
...@@ -110,6 +117,7 @@ GEM ...@@ -110,6 +117,7 @@ GEM
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
erubi (1.10.0) erubi (1.10.0)
execjs (2.8.1)
faraday (1.8.0) faraday (1.8.0)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0) faraday-em_synchrony (~> 1.0)
...@@ -130,12 +138,14 @@ GEM ...@@ -130,12 +138,14 @@ GEM
faraday-patron (1.0.0) faraday-patron (1.0.0)
faraday-rack (1.0.0) faraday-rack (1.0.0)
ffi (1.15.4) ffi (1.15.4)
font-awesome-rails (4.7.0.7)
railties (>= 3.2, < 7)
globalid (0.5.2) globalid (0.5.2)
activesupport (>= 5.0) activesupport (>= 5.0)
httparty (0.18.1) httparty (0.18.1)
mime-types (~> 3.0) mime-types (~> 3.0)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (1.8.10) i18n (1.8.11)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
jbuilder (2.11.2) jbuilder (2.11.2)
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
...@@ -152,11 +162,12 @@ GEM ...@@ -152,11 +162,12 @@ GEM
mail (2.7.1) mail (2.7.1)
mini_mime (>= 0.1.1) mini_mime (>= 0.1.1)
marcel (1.0.2) marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0) method_source (1.0.0)
mime-types (3.3.1) mime-types (3.3.1)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2021.0901) mime-types-data (3.2021.0901)
mini_mime (1.1.1) mini_mime (1.1.2)
minitest (5.14.4) minitest (5.14.4)
msgpack (1.4.2) msgpack (1.4.2)
multi_xml (0.6.0) multi_xml (0.6.0)
...@@ -169,15 +180,16 @@ GEM ...@@ -169,15 +180,16 @@ GEM
parallel (1.21.0) parallel (1.21.0)
parser (3.0.2.0) parser (3.0.2.0)
ast (~> 2.4.1) ast (~> 2.4.1)
popper_js (1.16.0)
pry (0.14.1) pry (0.14.1)
coderay (~> 1.1) coderay (~> 1.1)
method_source (~> 1.0) method_source (~> 1.0)
pry-rails (0.3.9) pry-rails (0.3.9)
pry (>= 0.10.4) pry (>= 0.10.4)
public_suffix (4.0.6) public_suffix (4.0.6)
puma (5.5.0) puma (5.5.2)
nio4r (~> 2.0) nio4r (~> 2.0)
racc (1.5.2) racc (1.6.0)
rack (2.2.3) rack (2.2.3)
rack-mini-profiler (2.3.3) rack-mini-profiler (2.3.3)
rack (>= 1.2.0) rack (>= 1.2.0)
...@@ -226,7 +238,7 @@ GEM ...@@ -226,7 +238,7 @@ GEM
faraday (>= 0.9.0) faraday (>= 0.9.0)
rsolr-ext (1.0.3) rsolr-ext (1.0.3)
rsolr (>= 1.0.2) rsolr (>= 1.0.2)
rubocop (1.22.0) rubocop (1.22.3)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.0.0.0) parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
...@@ -235,9 +247,9 @@ GEM ...@@ -235,9 +247,9 @@ GEM
rubocop-ast (>= 1.12.0, < 2.0) rubocop-ast (>= 1.12.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0) unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.12.0) rubocop-ast (1.13.0)
parser (>= 3.0.1.1) parser (>= 3.0.1.1)
rubocop-rails (2.12.2) rubocop-rails (2.12.4)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0) rubocop (>= 1.7.0, < 2.0)
...@@ -254,8 +266,9 @@ GEM ...@@ -254,8 +266,9 @@ GEM
sprockets (> 3.0) sprockets (> 3.0)
sprockets-rails sprockets-rails
tilt tilt
selenium-webdriver (3.142.7) selenium-webdriver (4.0.3)
childprocess (>= 0.5, < 4.0) childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2) rubyzip (>= 1.2.2)
semantic_range (3.0.0) semantic_range (3.0.0)
slim (4.1.0) slim (4.1.0)
...@@ -290,10 +303,10 @@ GEM ...@@ -290,10 +303,10 @@ GEM
activemodel (>= 6.0.0) activemodel (>= 6.0.0)
bindex (>= 0.4.0) bindex (>= 0.4.0)
railties (>= 6.0.0) railties (>= 6.0.0)
webdrivers (4.6.1) webdrivers (5.0.0)
nokogiri (~> 1.6) nokogiri (~> 1.6)
rubyzip (>= 1.3.0) rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0) selenium-webdriver (~> 4.0)
webpacker (5.4.3) webpacker (5.4.3)
activesupport (>= 5.2) activesupport (>= 5.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
...@@ -304,7 +317,7 @@ GEM ...@@ -304,7 +317,7 @@ GEM
websocket-extensions (0.1.5) websocket-extensions (0.1.5)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.4.2) zeitwerk (2.5.1)
PLATFORMS PLATFORMS
x86_64-linux x86_64-linux
...@@ -312,10 +325,12 @@ PLATFORMS ...@@ -312,10 +325,12 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
active_storage_validations (~> 0.9.5) active_storage_validations (~> 0.9.5)
bootsnap (>= 1.4.4) bootsnap (>= 1.4.4)
bootstrap (~> 4.4.1)
bullet (~> 6.1, >= 6.1.4) bullet (~> 6.1, >= 6.1.4)
byebug byebug
capybara (>= 3.26) capybara (>= 3.26)
devise (~> 4.8) devise (~> 4.8)
font-awesome-rails (~> 4.7, >= 4.7.0.7)
httparty (~> 0.18.1) httparty (~> 0.18.1)
jbuilder (~> 2.7) jbuilder (~> 2.7)
jquery-rails (~> 4.4) jquery-rails (~> 4.4)
......
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, or any plugin's
* vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
@import "bootstrap";
@import "font-awesome";
@import "./scss/style.scss";
.ribbon {
text-align: center;
ul {
list-style: none;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
margin: 0;
padding: 0;
.item {
display: block;
float: left;
width: 30%;
height: 100%;
background: #f3f5fa;
text-align: center;
padding: 8px;
position: relative;
font-size: 16px;
font-weight: 700;
text-decoration: none;
color: #808080;
.circle {
display: inline-flex;
-ms-flex-line-pack: center;
align-content: center;
-ms-flex-pack: center;
justify-content: center;
width: 1.6em;
height: 1.6em;
padding: 0.25em 0;
margin-right: 10px;
line-height: 1em;
font-size: 1em;
color: #808080;
background-color: #e0e0e0;
border-radius: 50%;
}
&:after {
content: "";
border-top: 21px solid transparent;
border-bottom: 21px solid transparent;
border-left: 21px solid #f3f5fa;
position: absolute;
right: -21px;
top: 0;
z-index: 1;
}
&:last-child::after {
display: none;
}
&:first-child::before {
content: "";
border-top: 21px solid transparent;
border-bottom: 21px solid transparent;
border-left: 21px solid #fff;
position: absolute;
left: 0;
top: 0;
}
}
.active {
background: #0d6efd;
color: #fff;
.circle {
color: #0d6efd;
background-color: #fff;
}
&::after {
border-left-color: #0d6efd;
color: #fff;
}
}
}
}
.btn-height {
height: 50px;
}
.invalid {
.form-msg {
color: #f33a58;
}
input {
border-color: #f33a58;
}
}
.logout {
border: none;
padding: 0;
background-color: white;
outline: none;
}
.flash {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 1000;
background-color: white;
}
.hide {
display: none;
}
.alert-notice {
color: #155724;
background-color: #d4edda;
border-color: #c3e6cb;
}
\ No newline at end of file
// Place all the styles related to the Favorite_industries controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
/* About Content */
.about-content {
& .title {
margin-bottom: 20px;
}
& p {
margin-bottom: 20px;
}
& ul {
padding-left: 15px;
}
}
/* About Image */
.about-image {
height: 100%;
& img {
height: 100%;
object-fit: cover;
object-position: center;
}
}
\ No newline at end of file
/*----
/* 02.1 Accordion Elements CSS
/*----------------------------------------*/
.accordion {
& .card {
& .card-header {
background-color: transparent;
& .btn {
padding: 0;
color: $heading-color;
&:hover {
text-decoration: none;
color: $primary;
}
}
}
& .card-body {
}
}
}
\ No newline at end of file
/* App Content */
.app-content {
margin-bottom: 30px;
& .title {
margin-bottom: 15px;
}
& .lead {
max-width: 490px;
margin-bottom: 30px;
}
@media #{$tablet-device} {
& .title {
font-size: 32px;
}
}
}
/* App Image */
.app-image {
}
\ No newline at end of file
/*----
/* 02.2 Blockquote Elements CSS
/*----------------------------------------*/
.blockquote {
margin-top: 20px;
padding: 20px 30px;
border: 1px solid #EDEDED;
& p {
font-family: $special-font;
font-style: italic;
color: $heading-color;
}
}
.blockquote-footer {
font-size: 14px;
margin-top: 5px;
color: $primary;
}
\ No newline at end of file
/* Blog Wrapper */
.blog-wrap {
margin-bottom: -30px;
& > [class*="col"] {
margin-bottom: 30px;
}
}
/* Blog */
.blog {
& .media {
margin-bottom: 25px;
& a {
display: block;
width: 100%;
}
& img {
width: 100%;
}
}
& .content {
& .title {
font-size: 19px;
margin-bottom: 15px;
& a {
}
}
& .meta {
font-size: 13px;
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
padding: 0;
list-style: none;
& li {
margin-top: 0;
margin-right: 10px;
&:last-child {
margin-right: 0;
}
&:not(:last-child)::after {
margin-left: 10px;
content: "-";
}
& a {
}
}
}
& .desc {
margin-bottom: 20px;
& p {
}
}
& .read-more {
font-weight: 600;
color: $heading-color;
& i {
margin-left: 5px;
}
&:hover {
color: $primary;
}
}
& .blog-tags {
display: flex;
flex-wrap: wrap;
& ul {
display: flex;
flex-wrap: wrap;
margin: 0;
padding-left: 0;
list-style: none;
& li {
margin-top: 0;
margin-right: 5px;
&::after {
content: ",";
}
&:first-child {
margin-right: 10px;
&::after {
display: none;
}
}
&:last-child {
margin-right: 0;
}
& a {
}
}
}
}
& .blog-share {
display: flex;
flex-wrap: wrap;
& ul {
display: flex;
align-items: center;
flex-wrap: wrap;
margin: 0;
padding-left: 0;
list-style: none;
& li {
margin-top: 0;
margin-right: 5px;
&:first-child {
margin-right: 10px;
}
&:last-child {
margin-right: 0;
}
& a {
width: 30px;
height: 30px;
text-align: center;
border-radius: 50%;
background-color: rgba($black, 0.075);
& i {
line-height: 32px;
}
&:hover {
color: $white;
background-color: $primary;
}
}
}
}
}
}
// Blog Single
&.blog-single {
& .content {
& .title {
font-size: 23px;
}
& .desc {
margin-bottom: 30px;
}
}
}
}
/* Blog Navigation */
.blog-navigation {
padding: 20px 0;
list-style: none;
border-top: 1px solid #EDEDED;
border-bottom: 1px solid #EDEDED;
& li {
margin: 0;
& a {
position: relative;
&:hover {
color: $primary;
&::before {
color: $primary;
}
}
&::before {
font-family: $fontawesome;
font-size: 30px;
line-height: 24px;
position: absolute;
top: 0;
color: $body-light;
}
&.prev-blog {
margin-left: -15px;
padding-left: 30px;
text-align: left;
&::before {
left: 0;
content: "\f104";
}
}
&.next-blog {
margin-right: -15px;
padding-right: 30px;
text-align: right;
&::before {
right: 0;
content: "\f105";
}
}
}
}
}
\ No newline at end of file
/*----
/* 02.3 Button Elements CSS
/*----------------------------------------*/
.btn {
line-height: 24px;
padding: 10px 30px;
border-radius: 0;
}
.btn-lg {
padding: 20px 35px;
}
\ No newline at end of file
/* Comment List */
.comment-list {
margin: 0;
padding-left: 0;
list-style: none;
& > li {
margin: 0;
&:last-child {
& .comment {
&:last-child {
margin-bottom: 0;
}
}
}
}
}
/* Child Comment */
.child-comment {
margin: 0;
padding-left: 40px;
list-style: none;
& > li {
margin: 0;
}
@media #{$extra-small-mobile} {
padding-left: 0;
}
}
/* Comment */
.comment {
display: flex;
flex-wrap: wrap;
margin-bottom: 30px;
& .image {
width: 80px;
& img {
}
}
& .content {
max-width: calc(100% - 80px);
padding-left: 30px;
& .head {
display: flex;
align-items: center;
flex-wrap: wrap;
margin-bottom: 5px;
& .name {
font-size: 16px;
margin-right: 10px;
margin-bottom: 0;
}
& .date {
line-height: 1;
display: block;
color: $body-light;
&::before {
margin-right: 10px;
content: "-";
}
}
}
& p {
margin-bottom: 5px;
}
& .reply {
line-height: 1;
text-transform: capitalize;
color: $primary;
&:hover {
text-decoration: underline;
}
}
}
@media #{$extra-small-mobile} {
& .content {
max-width: 100%;
padding-top: 15px;
padding-left: 0;
}
}
}
\ No newline at end of file
@mixin placeholder {
&::-webkit-input-placeholder {
@content
}
&:-moz-placeholder {
@content
}
&::-moz-placeholder {
@content
}
&:-ms-input-placeholder {
@content
}
}
// @include placeholder {
// font-style: italic;
// }
/*-- Google Font --*/
@import url("https://fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i|Open+Sans:300,300i,400,400i,600,600i,700,700i,800,800i|Playfair+Display:400,400i,700,700i,900,900i&display=swap");
/*-- Common Style --*/
*,
*::after,
*::before {
box-sizing: border-box;
}
html,
body,
.site-wrapper {
height: 100%;
}
body {
font-family: $body-font;
font-size: 14px;
font-weight: 400;
font-style: normal;
line-height: 1.75;
position: relative;
visibility: visible;
color: $body-color;
background-color: $white;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: $heading-font;
font-weight: 600;
line-height: 1.2;
margin-top: 0;
color: $heading-color;
}
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
line-height: inherit;
margin: 0;
}
h1,
.h1 {
font-size: 48px;
@media #{$large-mobile} {
font-size: 40px;
}
@media #{$small-mobile} {
font-size: 30px;
}
}
h2,
.h2 {
font-size: 40px;
@media #{$large-mobile} {
font-size: 30px;
}
@media #{$small-mobile} {
font-size: 24px;
}
}
h3,
.h3 {
font-size: 33px;
@media #{$large-mobile} {
font-size: 26px;
}
@media #{$small-mobile} {
font-size: 20px;
}
}
h4,
.h4 {
font-size: 28px;
@media #{$large-mobile} {
font-size: 22px;
}
@media #{$small-mobile} {
font-size: 18px;
}
}
h5,
.h5 {
font-size: 23px;
@media #{$large-mobile} {
font-size: 18px;
}
@media #{$small-mobile} {
font-size: 16px;
}
}
h6,
.h6 {
font-size: 19px;
@media #{$large-mobile} {
font-size: 16px;
}
@media #{$small-mobile} {
font-size: 14px;
}
}
p:last-child {
margin-bottom: 0;
}
a,
button {
line-height: inherit;
display: inline-block;
cursor: pointer;
text-decoration: none;
color: inherit;
}
a,
button,
img,
input {
transition: all 0.3s ease 0s;
}
*:focus {
outline: none !important;
}
a:focus {
text-decoration: none;
color: inherit;
outline: none;
}
a:hover {
text-decoration: none;
color: $primary;
}
button,
input[type="submit"] {
cursor: pointer;
}
img {
max-width: 100%;
}
input,
textarea {
@include placeholder {
opacity: 1;
}
}
ul {
&:last-child {
margin-bottom: 0;
}
& li {
& + li {
margin-top: 6px;
}
}
}
/*-- Common Classes --*/
.fix {
overflow: hidden;
}
.hidden {
display: none;
}
.clear {
clear: both;
}
.section,
.main-wrapper {
float: left;
width: 100%;
}
@media only screen and (min-width: 1200px) {
.container {
max-width: 1200px;
}
}
@media #{$small-mobile} {
.container {
max-width: 450px;
}
}
@media #{$extra-small-mobile} {
.container {
max-width: 300px;
}
}
.lead {
font-size: 18px;
font-weight: 400;
@media #{$large-mobile} {
font-size: 16px;
}
}
/*Background Color*/
.bg-white {
background-color: #FFFFFF !important;
}
.bg-gray {
background-color: $grey !important;
}
.bg-dark {
background-color: $heading-color !important;
}
@each $name,
$color in $templateColor {
.bg-#{$name} {
background-color: $color !important;
}
}
/*Text Color*/
.text-white {
color: $white !important;
}
.text-body {
color: $body-color !important;
}
.text-body-light {
color: $body-light !important;
}
.text-heading {
color: $heading-color !important;
}
@each $name,
$color in $templateColor {
.text-#{$name} {
color: $color !important;
}
}
/*Font Weight*/
.fw-100 {
font-weight: 100;
}
.fw-200 {
font-weight: 200;
}
.fw-300 {
font-weight: 300;
}
.fw-400 {
font-weight: 400;
}
.fw-500 {
font-weight: 500;
}
.fw-600 {
font-weight: 600;
}
.fw-700 {
font-weight: 700;
}
.fw-800 {
font-weight: 800;
}
.fw-900 {
font-weight: 900;
}
/*White Space*/
.white-space-nowrap {
white-space: nowrap;
}
/*--Tab Content & Pane Fix--*/
.tab-content {
width: 100%;
& .tab-pane {
display: block;
visibility: hidden;
overflow: hidden;
max-width: 100%;
height: 0;
opacity: 0;
&.active {
visibility: visible;
overflow: visible;
height: auto;
opacity: 1;
}
}
}
/*--Background Image--*/
[data-bg-image]:not(.bg-parallax) {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
/*--Background Parallax--*/
.bg-parallax {
background-repeat: no-repeat;
background-attachment: fixed;
background-position: 50% 0;
background-size: cover;
}
/*--Overlay--*/
[data-overlay] {
position: relative;
z-index: 1;
&::before {
position: absolute;
z-index: -1;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: "";
background-color: $black;
}
}
@for $i from 0 through 20 {
[data-overlay="#{$i * 5}"] {
&::before {
opacity: 0.05 * $i;
}
}
}
/*--Section Spacing--*/
.section-padding {
padding-top: 120px;
padding-bottom: 120px;
// Responsive
@media #{$desktop-device} {
padding-top: 100px;
padding-bottom: 100px;
}
@media #{$tablet-device} {
padding-top: 80px;
padding-bottom: 80px;
}
@media #{$large-mobile} {
padding-top: 60px;
padding-bottom: 60px;
}
}
/*--Section Title--*/
.section-title {
width: 100%;
margin-bottom: 70px;
text-align: center;
& .title {
margin-top: -5px;
margin-bottom: 0;
&:not(:last-child) {
margin-bottom: 10px;
}
}
& p {
font-size: 16px;
}
&.text-white {
& .title {
color: $white;
}
& p {
color: $white;
}
}
@media #{$tablet-device} {
margin-bottom: 50px;
& .title {
font-size: 33px;
}
& p {
font-size: 14px;
}
}
@media #{$large-mobile} {
margin-bottom: 40px;
& .title {
font-size: 28px;
}
& p {
font-size: 14px;
}
}
@media #{$small-mobile} {
& .title {
font-size: 24px;
}
}
}
/*Page Pagination*/
.page-pagination {
& ul {
display: flex;
flex-wrap: wrap;
margin-right: -15px;
margin-bottom: -15px;
padding: 0;
list-style: none;
& li {
font-size: 14px;
font-weight: 600;
line-height: 50px;
width: 50px;
height: 50px;
margin-right: 15px;
margin-bottom: 15px;
text-align: center;
& a {
display: block;
color: $heading-color;
border: none;
background-color: lighten($primary, 36);
&:hover {
color: $white;
background-color: $primary;
}
}
&.page-numbers {
width: auto;
& a {
padding: 0 20px;
}
}
&.active {
color: $white;
background-color: $primary;
}
}
}
&.center {
& ul {
justify-content: center;
}
}
&.right {
& ul {
justify-content: flex-end;
}
}
}
.height-100vh {
min-height: 100vh;
}
// Slick Slider Default style
.slick-slider {
& .slick-arrow {
opacity: 0;
}
&:hover {
& .slick-arrow {
opacity: 1;
}
}
}
// Slick Arrow
.slick-arrow {
position: absolute;
z-index: 9;
top: 50%;
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
padding: 0;
transform: translateY(-50%);
border: 2px solid #EDEDED;
border-radius: 50%;
background-color: $white;
&.slick-prev {
left: -10px;
}
&.slick-next {
right: -10px;
}
& i {
font-size: 20px;
}
&:hover {
color: $white;
border-color: $primary;
background-color: $primary;
}
}
// Slick Dots
.slick-dots {
display: flex;
justify-content: center;
margin-top: 30px;
margin-bottom: 0;
padding-left: 0;
list-style: none;
& li {
margin: 0 5px;
& button {
display: block;
overflow: hidden;
width: 14px;
height: 14px;
padding: 0;
text-indent: -9999px;
border: 2px solid #DDDDDD;
border-radius: 50%;
background-color: transparent;
}
&.slick-active {
& button {
border-color: $primary;
}
}
}
}
/* Scroll Up */
#scrollUp {
right: 25px;
bottom: 25px;
width: 40px;
height: 40px;
text-align: center;
color: $white;
background-color: $primary;
& i {
line-height: 40px;
}
}
\ No newline at end of file
/* Company Slider */
.company-slider {
}
/* Feature Company */
.feature-company {
display: block;
text-align: center;
& .company-logo {
display: inline-block;
margin-bottom: 10px;
}
& .title {
font-size: 19px;
transition: all 0.3s ease 0s;
}
& .open-job {
display: block;
color: $body-color;
}
&:hover {
& .title {
color: $primary;
}
}
}
/* Company List Wrapper */
.company-list-wrap {
margin-bottom: -30px;
& > div,
& > [class*="col"] {
margin-bottom: 30px;
}
}
/* Company List */
.company-list {
display: block;
padding: 30px;
text-align: center;
border: 1px solid #EDEDED;
& .company-logo {
display: inline-block;
margin-bottom: 10px;
}
& .title {
font-size: 19px;
transition: all 0.3s ease 0s;
}
& .open-job {
display: block;
margin-bottom: 6px;
color: $body-color;
}
& .location {
font-size: 13px;
color: $body-color;
& i {
margin-right: 10px;
}
}
&:hover {
z-index: 9;
border-color: transparent;
box-shadow: 0 0 30px rgba($black, 0.15);
& .title {
color: $primary;
}
}
}
\ No newline at end of file
/* Contact Map */
.contact-map {
padding-bottom: 40%;
@media #{$extra-small-mobile} {
padding-bottom: 60%;
}
}
/* Google Map */
.google-map {
background-color: #EDEDED;
}
/* Contact Information */
.contact-information {
& ul {
padding-left: 0;
list-style: none;
& li {
& + li {
margin-bottom: 10px;
}
& i {
margin-right: 15px;
}
}
}
}
/* Contact Social */
.contact-social {
display: flex;
flex-wrap: 0;
margin: -5px;
& a {
width: 36px;
height: 36px;
margin: 5px;
text-align: center;
border-radius: 50%;
background-color: rgba($black, 0.075);
& i {
line-height: 36px;
}
&:hover {
color: $white;
background-color: $primary;
}
}
}
\ No newline at end of file
/* Faq Card */
.faq-card {
margin-bottom: 30px;
border: none;
&:last-child {
margin-bottom: 0;
}
& .card-header {
padding: 0;
border: none;
background-color: transparent;
}
& .card-body {
padding: 0 0 0 28px;
}
}
\ No newline at end of file
/* Footer Top Section */
.footer-top-section {
padding: 80px 0;
background-color: #333333;
}
/* Footer Widget Wrapper */
.footer-widget-wrap {
margin-bottom: -30px;
}
/* Footer Widget */
.footer-widget {
margin-bottom: 30px;
color: lighten($body-color, 25);
& .title {
font-size: 19px;
line-height: 1;
margin-bottom: 20px;
color: $white;
}
}
/* Footer About */
.footer-widget-about {
& img {
margin-bottom: 20px;
}
& p {
max-width: 250px;
&:not(:last-child) {
margin-bottom: 20px;
}
}
}
/* Footer Social */
.footer-socail {
display: flex;
flex-wrap: wrap;
margin: 0 -5px -5px;
padding-left: 0;
list-style: none;
& li {
margin: 0 5px 5px;
& a {
display: flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
color: $white;
border-radius: 50%;
background-color: rgba($white, 0.1);
&:hover {
background-color: $primary;
}
& i {
}
}
}
}
/* Footer Link */
.footer-widget-link {
& ul {
margin: 0;
padding-left: 0;
list-style: none;
& li {
& + li {
margin-top: 6px;
}
& a {
}
}
}
}
/* Footer Newsletter */
.footer-widget-newsletter {
& p {
margin-bottom: 20px;
}
& form {
position: relative;
& input {
font-size: 13px;
padding-right: 44px;
color: $white;
border: none;
background-color: rgba($white, 0.1);
}
& button {
position: absolute;
top: 0;
right: 0;
width: 44px;
padding: 10px;
color: $white;
border: none;
&:hover {
color: $white;
background-color: $primary;
}
}
}
}
/* Footer Bottom Section */
.footer-bottom-section {
padding: 20px 0;
background-color: $black;
}
/* Footer Copyright */
.footer-copyright {
color: lighten($body-color, 25);
& a {
color: $primary;
&:hover {
text-decoration: underline;
}
}
}
\ No newline at end of file
/*----
/* 02.4 Form Elements CSS
/*----------------------------------------*/
label {
font-size: 13px;
line-height: 1.25;
display: block;
margin-bottom: 10px;
}
input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
textarea,
.form-control {
line-height: 24px;
display: block;
width: 100%;
padding: 10px 20px;
color: $body-color;
border: 1px solid #EDEDED;
border-radius: 0;
background-color: $white;
}
select {
line-height: 24px;
display: block;
width: 100%;
padding: 10px 15px;
padding-right: 40px;
color: $body-color;
border: 1px solid #EDEDED;
border-radius: 0;
background-color: $white;
// background-image: url("../images/icons/arrow-down.png");
background-repeat: no-repeat;
background-position: right center;
background-size: auto;
appearance: none;
}
// Custom Control Label
.custom-control-label {
font-size: inherit;
line-height: 1.65;
}
// Range Slider
.range-slider {
&.irs-hidden-input {
position: absolute;
top: 0;
left: 0;
display: block;
visibility: hidden;
width: 0;
height: 0;
opacity: 0;
}
}
// Ion Range Slider
.irs {
position: relative;
display: block;
width: 100%;
& .irs {
position: relative;
display: block;
padding-top: 30px;
& .irs-line {
display: block;
width: 100%;
height: 6px;
background-color: #F2F2F2;
}
& .irs-min {
display: none;
}
& .irs-max {
display: none;
}
& .irs-from {
position: absolute;
top: 0;
visibility: visible !important;
white-space: nowrap;
}
& .irs-to {
position: absolute;
top: 0;
visibility: visible !important;
white-space: nowrap;
}
& .irs-single {
display: none;
}
}
& .irs-grid {
display: none;
}
& .irs-bar {
position: absolute;
bottom: 0;
height: 6px;
background-color: $primary;
}
& .irs-handle {
position: absolute;
bottom: -7px;
display: block;
width: 20px;
height: 20px;
border-radius: 50px;
background-color: $primary;
box-shadow: 0 0 15px rgba($black, 0.3);
& i {
display: none;
}
&.from {
}
&.to {
}
}
}
\ No newline at end of file
/* Funfact Wrapper */
.funfact-wrap {
margin-bottom: -30px;
}
/* Funfact */
.funfact {
margin-bottom: 30px;
text-align: center;
color: $white;
& span {
line-height: 1;
display: block;
}
& .counter {
font-size: 50px;
margin-bottom: 10px;
}
& .title {
font-size: 23px;
line-height: 1.25;
}
// Responsive
@media #{$large-mobile} {
& .title {
font-size: 19px;
}
}
}
\ No newline at end of file
.header {
position: absolute;
z-index: 99;
top: 0;
left: 0;
width: 100%;
padding: 30px 0;
transition: all 0.3s ease 0s;
&.is-sticky {
position: fixed;
padding: 15px 0;
background-color: $primary;
box-shadow: 0 0 30px rgba($black, 0.2);
}
&.menu-open {
background-color: $primary;
box-shadow: 0 0 30px rgba($black, 0.2);
}
// Responsive
@media #{$large-mobile} {
padding: 20px 0 !important;
}
}
/* Header Logo */
.header-logo {
& a {
display: blocks;
& img {
}
}
// Responsive
@media #{$large-mobile} {
& a {
width: 150px;
}
}
@media #{$extra-small-mobile} {
& a {
width: 130px;
}
}
}
/* Offcanvas Toggle */
.offcanvas-toggle {
position: relative;
width: 30px;
height: 20px;
padding: 0;
border: none;
background-color: transparent;
& span {
display: block;
width: 90%;
height: 1px;
transition: all 0.3s ease 0s;
background-color: $white;
&::before,
&::after {
position: absolute;
left: 0;
height: 1px;
content: "";
transition: all 0.3s ease 0s;
background-color: $white;
}
&::before {
top: 0;
width: 100%;
}
&::after {
bottom: 0;
width: 80%;
}
}
&:hover {
& span {
width: 70%;
&::before {
width: 85%;
}
&::after {
width: 100%;
}
}
}
}
/* Header Links */
.header-links {
display: flex;
align-items: center;
margin-left: 45px;
color: $white;
& a {
font-weight: 600;
&:hover {
text-decoration: underline;
color: inherit;
}
}
& span {
margin: 0 10px;
}
// Responsive
@media #{$tablet-device,
$large-mobile
} {
display: none;
}
@media #{$large-mobile} {
margin-left: 0;
}
}
/* Main Menu */
.main-menu {
display: flex;
align-items: center;
& > ul {
display: flex;
flex-wrap: wrap;
margin: 0;
padding: 0;
list-style: none;
color: $white;
& > li {
position: relative;
margin-top: 0;
padding: 15px 0;
& + li {
margin-left: 45px;
}
& > a {
position: relative;
display: black;
padding: 0;
&::before {
position: absolute;
right: 0;
bottom: 0;
width: 0;
height: 1px;
content: "";
transition: all 0.3s ease 0s;
background-color: $white;
}
}
&.active,
&:hover {
& > a {
color: $white;
&::before {
right: auto;
left: 0;
width: 100%;
}
}
}
&:hover {
& > .sub-menu {
visibility: visible;
opacity: 1;
}
}
}
}
@media #{$desktop-device} {
& > ul {
& > li {
& + li {
margin-left: 30px;
}
}
}
}
@media #{$tablet-device,
$large-mobile
} {
display: none;
width: 100%;
& > ul {
flex-direction: column;
margin-top: 20px;
& > li {
padding: 0;
& + li {
margin-top: 20px;
margin-left: 0;
}
& > a {
&::before {
display: none;
}
&.active {
padding-left: 12px;
border-left: 4px solid $white;
}
}
}
}
}
}
/* Sub Menu */
.sub-menu {
font-size: 13px;
position: absolute;
top: 100%;
left: -20px;
visibility: hidden;
width: 200px;
padding: 20px;
list-style: none;
transition: all 0.3s ease 0s;
opacity: 0;
color: $body-color;
background-color: $white;
box-shadow: 0 10px 20px rgba($black, 0.15);
& li {
& + li {
margin-top: 5px;
}
& a {
display: block;
}
}
}
/* Off Canvas CSS */
body.offcanvas-open {
overflow: hidden;
}
/* Off Canvas Section */
.offcanvas-section {
position: fixed;
z-index: 998;
top: 0;
right: -100%;
left: auto;
visibility: hidden;
width: 390px;
height: 100%;
padding-left: 60px;
transition: all 0.3s ease 0s;
opacity: 0;
&.open {
right: 0;
visibility: visible;
opacity: 1;
& .offcanvas-close {
visibility: visible;
opacity: 1;
}
}
// Responsive
@media #{$extra-small-mobile} {
width: 100%;
padding-left: 50px;
}
}
/* OffCanvas Overlay */
.offcanvas-overlay {
position: fixed;
z-index: 996;
top: 0;
left: 0;
display: none;
width: 100%;
height: 100%;
background-color: rgba($black, 0.8);
}
/* OffCanvas Wraper */
.offcanvas-wrap {
overflow-x: hidden;
overflow-y: auto;
height: 100%;
background-color: $white;
box-shadow: -5px 0 5px 0 rgba($black, 0.1);
& .inner {
display: flex;
flex-direction: column;
min-height: 100%;
padding: 40px 30px;
}
}
/* OffCanvas Close */
.offcanvas-close {
font-size: 24px;
font-weight: 300;
line-height: 1;
position: absolute;
z-index: 997;
top: 10px;
left: 10px;
visibility: hidden;
width: 50px;
height: 50px;
transition: all 0.3s ease 0s;
opacity: 0;
color: $heading-color;
border: none;
background-color: $white;
box-shadow: -5px 0 5px 0 rgba($black, 0.1);
// Responsive
@media #{$extra-small-mobile} {
width: 40px;
height: 40px;
}
}
/* OffCanvas Menu */
.offcanvas-menu {
& nav {
& ul {
font-size: 13px;
position: static;
top: 0;
left: 0;
visibility: visible;
width: 100%;
margin: 0;
padding: 0;
padding: 0;
list-style: none;
transition: none;
opacity: 1;
background-color: transparent;
box-shadow: none;
& li {
position: relative;
& a {
font-weight: 500;
line-height: 1;
display: block;
padding: 15px 0;
text-transform: uppercase;
border-bottom: 1px solid #EEEEEE;
}
&:last-child {
& > a {
border-bottom: none;
}
}
// Menu Expand Toggle Button For Submenu
& .menu-expand {
line-height: 44px;
position: absolute;
z-index: 5;
top: 0;
right: 0;
width: 30px;
height: 44px;
cursor: pointer;
text-align: center;
& i {
position: relative;
display: block;
width: 10px;
margin-top: 22px;
margin-right: auto;
margin-left: auto;
transition: all 250ms ease-out;
border-bottom: 1px solid;
&::before {
position: absolute;
top: 0;
display: block;
width: 100%;
content: "";
transition: all 250ms ease-out;
transform: rotate(90deg);
border-bottom: 1px solid;
}
}
&:hover {
& i {
border-color: $primary;
&::before {
border-color: $primary;
}
}
}
}
&:hover {
}
&.active {
& > .menu-expand {
& i {
&::before {
transform: rotate(0deg);
}
}
}
& > .sub-menu {
border-bottom: 1px solid #EEEEEE;
}
}
}
}
}
& .sub-menu {
display: none;
& li {
padding: 0 15px;
& a {
font-size: 13px;
text-transform: inherit;
}
}
}
}
/* OffCanvas User */
.offcanvas-user {
display: flex;
align-items: center;
margin-bottom: 30px;
& a {
flex-grow: 1;
padding: 7px 15px;
text-align: center;
color: $white;
background-color: #6C757D;
&:hover {
border-color: $primary;
background-color: $primary;
}
&:focus {
color: $white;
box-shadow: none;
}
}
& span {
padding: 10px;
}
}
\ No newline at end of file
/* Job Category Slider */
.job-category-slider {
& .slick-list {
padding-top: 15px;
padding-bottom: 15px;
}
}
/* Job Category */
.job-category {
display: flex;
align-items: center;
justify-content: center;
height: 190px;
transition: all 0.3s ease 0s;
text-align: center;
& .inner {
& i {
font-size: 50px;
line-height: 1;
display: block;
}
& .title {
font-size: 14px;
font-weight: 600;
margin-top: 20px;
margin-bottom: 0;
text-transform: uppercase;
color: inherit;
}
}
}
\ No newline at end of file
/* Job Search Section */
.job-search-section {
position: relative;
z-index: 90;
}
/* Job Search Wrapper */
.job-search-wrap {
position: relative;
margin-top: -83px;
padding: 60px;
background-color: $white;
box-shadow: 0 0 30px rgba($black, 0.15);
// Responsive
@media #{$extra-small-mobile} {
padding: 30px;
}
}
/* Job Search Form */
.job-search-form {
& .btn {
display: block;
width: 100%;
}
}
/* Job Search Form 2 */
.job-search-form-2 {
& input[type="text"] {
padding: 15px 20px;
}
& select {
padding: 15px;
padding-right: 40px;
}
& .btn {
display: block;
width: 100%;
padding: 15px 20px;
}
}
\ No newline at end of file
.job-list-details {
& .job-details-head {
position: relative;
z-index: 1;
align-items: center;
margin-bottom: 30px;
padding-bottom: 25px;
border-bottom: 1px solid #EDEDED;
& .company-logo {
}
& .salary-type {
text-align: right;
& .salary-range {
font-weight: 600;
line-height: 1;
display: block;
margin-bottom: 8px;
color: lighten($body-color, 15);
}
& .badge {
font-size: 13px;
font-weight: 400;
padding: 4px 10px 5px;
border-radius: 0;
}
}
& .content {
& .title {
}
& .meta {
display: flex;
flex-wrap: wrap;
margin-bottom: 0;
padding-left: 0;
list-style: none;
color: lighten($body-color, 15);
& li {
margin-top: 0;
margin-right: 20px;
&:last-child {
margin-right: 0;
}
& i {
font-size: 16px;
margin-right: 3px;
}
}
}
}
// Responsive
@media #{$small-mobile} {
& .salary-type {
margin-left: auto;
}
& .content {
flex: 1 0 100%;
margin-top: 10px;
}
}
@media #{$extra-small-mobile} {
padding: 20px 5px;
}
}
& .job-details-body {
& ul {
padding-left: 25px;
}
}
}
\ No newline at end of file
/* Job List Toolbar */
.job-list-toolbar {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
margin: -10px -10px 20px;
& p {
display: flex;
align-items: center;
margin: 0;
padding: 10px;
white-space: nowrap;
& select {
margin-left: 10px;
}
}
}
/* Job List Wrapper */
.job-list-wrap {
padding: 1px;
}
/* Job List */
.job-list {
position: relative;
z-index: 1;
display: flex;
align-items: center;
flex-wrap: wrap;
margin: -1px;
padding: 23px 15px;
border-width: 1px;
border-style: solid;
border-color: #EDEDED transparent;
&:hover {
z-index: 9;
border-color: transparent;
box-shadow: 0 0 30px rgba($black, 0.15);
}
& .company-logo {
}
& .salary-type {
text-align: right;
& .salary-range {
font-weight: 600;
line-height: 1;
display: block;
margin-bottom: 8px;
color: lighten($body-color, 15);
}
& .badge {
font-size: 13px;
font-weight: 400;
padding: 4px 10px 5px;
border-radius: 0;
}
}
& .content {
& .title {
}
& .meta {
display: flex;
flex-wrap: wrap;
margin-bottom: 0;
padding-left: 0;
list-style: none;
color: lighten($body-color, 15);
& li {
margin-top: 0;
margin-right: 20px;
&:last-child {
margin-right: 0;
}
& i {
font-size: 16px;
margin-right: 3px;
}
}
}
}
// Responsive
@media #{$small-mobile} {
& .salary-type {
margin-left: auto;
& .badge {
font-size: 10px;
}
}
& .content {
flex: 1 0 100%;
margin-top: 10px;
}
}
@media #{$extra-small-mobile} {
padding: 20px 5px;
}
}
\ No newline at end of file
/* Login & Signup Tab Nav */
.loginSignupNav {
display: flex;
overflow: hidden;
flex: 1 0 100%;
flex-wrap: wrap;
margin: -20px -30px -21px;
text-align: center;
border-top-left-radius: 0.3rem;
border-top-right-radius: 0.3rem;
& li {
flex-grow: 1;
margin: 0;
& .nav-link {
padding: 15px 30px;
&.active {
color: $white;
background-color: $primary;
}
}
}
}
/* Login & Signup With Social */
.login-reg-social {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin: 0 -5px -10px;
& a {
display: inline-block;
width: 40px;
height: 40px;
margin: 0 5px 10px;
text-align: center;
border-radius: 50%;
background-color: #EDEDED;
& i {
line-height: 40px;
}
&:hover {
color: $white;
background-color: $primary;
}
}
}
\ No newline at end of file
/*----
/* 02.5 Button Elements CSS
/*----------------------------------------*/
.modal {
}
.modal-dialog {
}
.modal-content {
}
.modal-header {
position: relative;
padding: 20px 30px;
border-color: #EDEDED;
& .close {
font-weight: 300;
position: absolute;
top: -20px;
right: -20px;
width: 40px;
height: 40px;
margin: 0;
padding: 0 0 3px;
opacity: 1;
border-radius: 50%;
background-color: $white;
box-shadow: 0 0 30px rgba($black, 0.15);
&:hover {
opacity: 1 !important;
color: $white;
background-color: $primary;
}
}
}
.modal-body {
padding: 30px;
}
\ No newline at end of file
/* Page Heading Section */
.page-heading-section {
padding: 200px 0 100px;
@media #{$large-mobile} {
padding: 130px 0 50px;
}
}
/* Page Heading Content */
.page-heading-content {
& .title {
color: $white;
}
& .breadcrumb {
justify-content: center;
margin: 0;
padding: 0;
color: $white;
background-color: transparent;
& .breadcrumb-item {
&::before {
color: $white;
}
&.active {
text-decoration: underline;
color: $white;
}
}
}
}
\ No newline at end of file
/*----
/* 02.6 Button Elements CSS
/*----------------------------------------*/
.pagination {
margin: 0 0 -10px;
& .page-item {
margin: 0 5px 10px;
& .page-link {
font-size: 14px;
line-height: 25px;
width: 35px;
height: 35px;
padding: 5px;
text-align: center;
color: $body-color;
border: none;
border-radius: 0;
&:hover {
color: $white;
background-color: $primary;
}
}
&.active {
& .page-link {
color: $white;
background-color: $primary;
}
}
}
&.pagination-center {
justify-content: center;
}
}
\ No newline at end of file
/* Pricing Wrapper */
.pricing-wrap {
margin-bottom: -30px;
}
/* Pricing */
.pricing {
margin-bottom: 30px;
& .inner {
padding: 40px;
border: 1px solid #EDEDED;
background-color: $white;
& .head {
margin-bottom: 40px;
& .title {
font-weight: 600;
line-height: 1;
display: block;
margin-bottom: 20px;
text-transform: uppercase;
}
& .price {
font-size: 50px;
line-height: 1;
margin-bottom: 5px;
& sup {
font-size: 20px;
margin-right: 3px;
vertical-align: super;
&:last-child {
margin-right: 0;
vertical-align: sub;
}
}
}
& .duration {
line-height: 1;
display: block;
}
}
& .body {
margin-bottom: 40px;
& ul {
font-size: 16px;
margin-bottom: 0;
padding-left: 0;
list-style: none;
& li {
& + li {
margin-top: 5px;
}
}
}
}
& .foot {
& .btn {
padding: 10px 30px;
color: $white;
background-color: $dark;
&:hover {
background-color: $primary;
}
}
}
}
}
\ No newline at end of file
/* Sidebar Wrapper */
.sidebar-wrap {
margin-bottom: -35px;
}
/* Sidebar Widget */
.sidebar-widget {
margin-bottom: 35px;
& > .inner {
padding: 25px;
border: 1px solid #EDEDED;
& > .title {
font-size: 19px;
line-height: 1;
margin-bottom: 20px;
}
}
}
/* Sidebar Job Location Map */
.job-location-map {
width: 100%;
max-height: 300px;
padding-top: 100%;
}
/* Sidebar Banner */
.banner {
display: block;
border: 1px solid #EDEDED;
& img {
width: 100%;
}
}
/* Sidebar Company */
.sidebar-company {
display: block;
& .company-logo {
display: inline-block;
margin-bottom: 10px;
}
& .title {
font-size: 19px;
transition: all 0.3s ease 0s;
}
& ul {
margin: 0;
padding-left: 0;
list-style: none;
& li {
& strong {
margin-right: 6px;
color: $heading-color;
}
}
}
}
/* Sidebar Company Location Map */
.company-location-map {
width: 100%;
max-height: 250px;
padding-top: 100%;
}
/* Sidebar List */
.sidebar-list {
margin: 0;
padding: 0;
list-style: none;
& li {
line-height: 1.5;
& + li {
margin-top: 10px;
}
& a {
display: inline;
}
}
// Sidebar List Comment
&.sidebar-list-comment {
& li {
color: $body-light;
& + li {
margin-top: 15px;
}
& a {
color: $heading-color;
&:hover {
color: $primary;
}
}
}
}
}
/* Sidebar Post */
.sidebar-post {
margin: 0;
padding: 0;
list-style: none;
& li {
line-height: 1.5;
display: flex;
flex-wrap: wrap;
& + li {
margin-top: 15px;
}
& .image {
max-width: 70px;
margin-right: 15px;
}
& .title {
max-width: calc(100% - 85px);
}
}
}
\ No newline at end of file
.slide-item {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
height: 750px;
// Responsive
@media #{$desktop-device,
$tablet-device
} {
height: 650px;
}
@media #{$large-mobile} {
height: 450px;
}
@media #{$extra-small-mobile} {
height: 400px;
}
}
.slider-content {
& .title {
font-size: 96px;
font-weight: 700;
color: $white;
}
& p {
font-size: 28px;
margin: 0;
color: $white;
}
// Responsive
@media #{$desktop-device} {
& .title {
font-size: 86px;
}
}
@media #{$tablet-device} {
& .title {
font-size: 60px;
}
}
@media #{$large-mobile} {
& .title {
font-size: 50px;
}
& p {
font-size: 23px;
}
}
@media #{$small-mobile} {
& .title {
font-size: 40px;
}
& p {
font-size: 18px;
}
}
@media #{$extra-small-mobile} {
& .title {
font-size: 24px;
}
& p {
font-size: 14px;
}
}
}
.slide-item-2 {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
height: 750px;
// Responsive
@media #{$desktop-device,
$tablet-device
} {
height: 650px;
}
@media #{$large-mobile} {
height: 600px;
padding-top: 70px;
padding-bottom: 40px;
}
}
.slider-content-2 {
&:not(:last-child) {
margin-bottom: 30px;
}
& .title {
font-size: 50px;
font-weight: 700;
color: $white;
}
& p {
font-size: 18px;
margin: 0;
color: $white;
}
// Responsive
@media #{$small-mobile} {
& .title {
font-size: 40px;
}
}
@media #{$extra-small-mobile} {
& .title {
font-size: 24px;
}
& p {
font-size: 14px;
}
}
}
\ No newline at end of file
/* Team Wrapper */
.team-wrap {
margin-bottom: -30px;
& [class*="col"] {
margin-bottom: 30px;
}
}
/* Team */
.team {
position: relative;
overflow: hidden;
& img {
width: 100%;
}
& .content {
position: absolute;
z-index: 9;
top: 0;
left: 0;
display: flex;
align-items: flex-end;
flex-wrap: wrap;
width: 100%;
height: 100%;
transition: all 0.3s ease 0s;
transform: scale(1.25);
transform-origin: left bottom;
opacity: 0;
background-color: rgba($black, 0.7);
& .inner {
padding: 25px;
color: $white;
& .name {
font-size: 19px;
margin-bottom: 6px;
color: inherit;
}
& .title {
font-size: 13px;
line-height: 1;
display: block;
margin-bottom: 20px;
}
& .social {
display: flex;
flex-wrap: 0;
margin: -5px;
& a {
width: 30px;
height: 30px;
margin: 5px;
text-align: center;
border-radius: 50%;
background-color: rgba($white, 0.15);
& i {
line-height: 30px;
}
&:hover {
color: $white;
background-color: $primary;
}
}
}
}
}
&:hover {
& img {
transform: scale(1.15) rotate(5deg);
}
& .content {
transform: scale(1);
opacity: 1;
}
}
}
\ No newline at end of file
/* Testimonial Slider */
.testimonial-slider {
& .slick-arrow {
color: $white;
background-color: transparent;
&:hover {
background-color: $primary;
}
}
}
/* Testimonial */
.testimonial {
& p {
font-family: $special-font;
font-size: 24px;
max-width: 650px;
margin-right: auto;
margin-bottom: 30px;
margin-left: auto;
}
& img {
width: 70px;
margin-right: auto;
margin-bottom: 15px;
margin-left: auto;
border: 3px solid $grey;
border-radius: 50%;
}
& .name {
font-weight: 700;
color: inherit;
}
& .title {
font-size: 14px;
line-height: 1;
display: block;
}
}
\ No newline at end of file
// Font Family
$body-font: "Open Sans",
sans-serif;
$heading-font: "Montserrat",
sans-serif;
$special-font: "Playfair Display",
serif;
$fontawesome: "FontAwesome";
// Colors ---------------
$white: #FFFFFF;
$black: #000000;
$grey: #F8F9FD;
// Body Color
$body-color: #454545;
$body-light: #999999;
// Heading Color
$heading-color: #333333;
// Template Colors
$primary: #007BFF;
$secondary: #6C757D;
$success: #4CAF50;
$danger: #F44336;
$warning: #FFC107;
$info: #17A2B8;
$light: #F8F9FA;
$dark: #343A40;
$templateColor: ("primary": $primary,
"secondary": $secondary,
"success": $success,
"danger": $danger,
"warning": $warning,
"info": $info,
"light": $light,
"dark": $dark,
);
// Socail Color
$android: #7AC157;
$apple: #B8B8B8;
$behance: #1869FF;
$codepen: $black;
$dribbble: #EA4C8A;
$dropbox: #007EE5;
$evernote: #78D525;
$facebook: #4867AA;
$github: #313131;
$google-drive: #1DA462;
$google-earth: #4285F4;
$google-glass: #EA4335;
$google-maps: #5083C3;
$google-play: #01B9FD;
$google-plus: #DD5144;
$google: #4285F4;
$instagram: #B23A94;
$css3: #0277BD;
$html5: #E44D26;
$javascript: #F9DC3D;
$python: #0C9DBF;
$lastfm: #E31B23;
$linkedin: #007BB6;
$paypal: #002F86;
$pinterest: #BD081B;
$pocket: #EF3E56;
$polymer: #F87292;
$rss: #F99C3A;
$share: #2C9CFF;
$stackoverflow: #F38024;
$steam: #15497B;
$twitter: #1DA1F2;
$vk: #5181B8;
$wikipedia: #E9E9E9;
$windows: #0078D6;
$s500px: $black;
$s8tracks: #122D4B;
$amazon: #F79B34;
$blogger: #F06A35;
$delicious: #0000FE;
$disqus: #2E9EFE;
$flattr: #7AB831;
$flickr: #FE0084;
$odnoklassniki: #F58220;
$outlook: #0072C6;
$playstation: #07418E;
$reddit: #FF4500;
$skype: #00A9F0;
$slideshare: #0077B5;
$soundcloud: #FE4900;
$tumblr: #36465D;
$twitch: #6441A4;
$vimeo: #1AB7EA;
$whatsapp: #189D0E;
$xbox: #107C0F;
$yahoo: #4101AF;
$youtube: #FE0000;
// Responsive Variables
$extraBig-device: "only screen and (min-width: 1500px)";
$laptop-device: "only screen and (min-width: 1200px) and (max-width: 1499px)";
$desktop-device: "only screen and (min-width: 992px) and (max-width: 1199px)";
$tablet-device: "only screen and (min-width: 768px) and (max-width: 991px)";
$large-mobile: "only screen and (max-width: 767px)";
$small-mobile: "only screen and (max-width: 575px)";
$extra-small-mobile: "only screen and (max-width: 479px)";
\ No newline at end of file
/*-----------------------------------------------------------------------------------
Template Name: Edwards - Lawyers Attorneys and Law Firm HTML Template
Version: 1.0
-----------------------------------------------------------------------------------
CSS INDEX
===================
01. Theme default CSS
02. Elements CSS
02.1 Accordion Elements CSS
02.2 Blockquote Elements CSS
02.3 Button Elements CSS
02.4 Form Elements CSS
02.5 Modal Elements CSS
02.6 Pagination Elements CSS
03. Header CSS
04. Login Signup Modal CSS
05. Slider/Hero CSS
06. Page Heading/Title CSS
07. Job Search CSS
08. Jobs/Job List CSS
09. Job Single/Details CSS
10. Job Category CSS
11. Company CSS
12. Blog CSS
13. Comment CSS
14. Sidebar CSS
15. About CSS
16. Team CSS
17. Pricing CSS
18. APP CSS
19. Testimonial CSS
20. Funfact CSS
21. FAQ CSS
22. Contact CSS
23. Footer CSS
-----------------------------------------------------------------------------------*/
@import "variabls";
/*----------------------------------------*/
/* 01. Theme default CSS
/*----------------------------------------*/
@import "common";
/*----------------------------------------*/
/* 02. Elements CSS
/*----------------------------------------*/
@import "form";
@import "button";
@import "modal";
@import "accordion";
@import "pagination";
@import "blockquote";
/*----------------------------------------*/
/* 03. Header CSS
/*----------------------------------------*/
@import "header";
/*----------------------------------------*/
/* 04. Login Signup Modal CSS
/*----------------------------------------*/
@import "loginSignupModal";
/*----------------------------------------*/
/* 05. Slider/Hero CSS
/*----------------------------------------*/
@import "slider";
/*----------------------------------------*/
/* 06. Page Heading/Title CSS
/*----------------------------------------*/
@import "page-heading";
/*----------------------------------------*/
/* 07. Job Search CSS
/*----------------------------------------*/
@import "job-search";
/*----------------------------------------*/
/* 08. Jobs/Job List CSS
/*----------------------------------------*/
@import "jobs";
/*----------------------------------------*/
/* 09. Job Single/Details CSS
/*----------------------------------------*/
@import "job-single";
/*----------------------------------------*/
/* 10. Job Category CSS
/*----------------------------------------*/
@import "job-category";
/*----------------------------------------*/
/* 11. Company CSS
/*----------------------------------------*/
@import "company";
/*----------------------------------------*/
/* 12. Blog CSS
/*----------------------------------------*/
@import "blog";
/*----------------------------------------*/
/* 13. Comment CSS
/*----------------------------------------*/
@import "comment";
/*----------------------------------------*/
/* 14. Sidebar CSS
/*----------------------------------------*/
@import "sidebar";
/*----------------------------------------*/
/* 15. About CSS
/*----------------------------------------*/
@import "about";
/*----------------------------------------*/
/* 16. Team CSS
/*----------------------------------------*/
@import "team";
/*----------------------------------------*/
/* 17. Pricing CSS
/*----------------------------------------*/
@import "pricing";
/*----------------------------------------*/
/* 18. App CSS
/*----------------------------------------*/
@import "app";
/*----------------------------------------*/
/* 19. Testimonial CSS
/*----------------------------------------*/
@import "testimonial";
/*----------------------------------------*/
/* 20. Funfact CSS
/*----------------------------------------*/
@import "funfact";
/*----------------------------------------*/
/* 21. FAQ CSS
/*----------------------------------------*/
@import "faq";
/*----------------------------------------*/
/* 22. Contact CSS
/*----------------------------------------*/
@import "contact";
/*----------------------------------------*/
/* 23. Footer CSS
/*----------------------------------------*/
@import "footer";
\ No newline at end of file
// Top page
// search
// banner
.banner {
background-image: url('banner.jpg');
min-height: 200px;
background-repeat: no-repeat;
background-size: cover;
}
// latest-job
.latest-job {
.job-item {
font-size: 14px;
.job-title {
text-decoration: none;
color: black;
font-size: 20px;
font-weight: 500;
}
.job-caption {
line-height: 18px;
.job-company {
text-decoration: none;
font-size: 14px;
color: #495057;
}
.job-salary {
color: #008563;
margin: 0;
}
.job-locations {
ul {
list-style: none;
margin: 0 0 6px 0;
padding: 0;
color: #495057;
}
}
.job-desc {
overflow: hidden;
text-overflow: ellipsis;
line-height: 18px;
-webkit-line-clamp: 2;
max-height: 36px;
display: -webkit-box;
-webkit-box-orient: vertical;
}
}
}
}
// top_cities
.top_cities {
.city-item {
margin-bottom: 12px;
a {
font-size: 18px;
text-decoration: none;
color: #287ab9;
margin: 10px 0;
}
}
.all-cities-btn {
color: #287ab9;
font-size: 20px;
text-decoration: none;
}
.all-cities-btn:hover {
text-decoration: underline;
}
}
// top_industries
.top_industries {
.industry-item {
margin-bottom: 12px;
a {
font-size: 18px;
text-decoration: none;
color: #287ab9;
margin: 10px 0;
}
}
.all-industries-btn {
color: #287ab9;
font-size: 20px;
text-decoration: none;
}
.all-industries-btn:hover {
text-decoration: underline;
}
}
class FavoriteIndustriesController < ApplicationController
before_action :authenticate_user!
before_action :load_industry, only: %i[create destroy]
def index
@favorite_industries = current_user.favorite_industries
.page(params[:page]).per(Job::JOB_PER_PAGE)
end
def create
@favorite_industry = current_user.favorite_industries.build(industry_id: @industry.id)
respond_to :js if @favorite_industry.save
end
def destroy
@favorite_industry = current_user.favorite_industries.find_by(industry_id: @industry.id)
respond_to :js if @favorite_industry.destroy
end
private
def load_industry
@industry = Industry.find_by(id: params[:industry_id])
end
end
class FavoriteJobsController < ApplicationController class FavoriteJobsController < ApplicationController
# before_action :logged_in_user
before_action :authenticate_user! before_action :authenticate_user!
before_action :load_job, only: %i[create destroy] before_action :load_job, only: %i[create destroy]
......
class JobsController < ApplicationController class JobsController < ApplicationController
before_action :history, only: :show before_action :history, only: :show
before_action :views_count, only: :show
before_action :salary_search before_action :salary_search
before_action :city_industry_list before_action :city_industry_list
before_action :name, only: :index before_action :name, only: :index
...@@ -31,6 +32,13 @@ class JobsController < ApplicationController ...@@ -31,6 +32,13 @@ class JobsController < ApplicationController
history.update(updated_at: Time.current) history.update(updated_at: Time.current)
end end
def views_count
job = Job.find_by(id: params[:id])
count = job.views_count + 1
job.update_attribute :views_count, count
end
def name def name
@name = if params[:city_slug] @name = if params[:city_slug]
City.find_by(slug: params[:city_slug]).name City.find_by(slug: params[:city_slug]).name
...@@ -44,6 +52,6 @@ class JobsController < ApplicationController ...@@ -44,6 +52,6 @@ class JobsController < ApplicationController
def get_jobs(query) def get_jobs(query)
jobs_ids = query['response']['docs'].map { |j| j['job_id'] } jobs_ids = query['response']['docs'].map { |j| j['job_id'] }
@jobs = Job.eager_load(:cities, :cities_jobs, :company).find(jobs_ids) @jobs = Job.eager_load(:cities, :cities_jobs, :company).find(jobs_ids)
@jobs_count = query['numFound'] @jobs_count = query['response']['numFound']
end end
end end
class TopController < ApplicationController class TopController < ApplicationController
before_action :salary_search before_action :salary_search
before_action :city_industry_list before_action :city_industry_list
before_action :solr
def index def index
solr = Solr.new(params) @latest_jobs = get_jobs(@solr.latest_jobs)
@latest_jobs = get_jobs(solr.latest_jobs) @attractive_jobs = Job.top_views
@total_job = solr.query_all['response']['numFound'] @total_job = @solr.query_all['response']['numFound']
@total_job = 100 @top_cities = @solr.facet_query('city_id')['vietnam'].take(City::TOP_JOB_COUNT)
@top_cities = solr.facet_query('city_id')['vietnam'].take(City::TOP_JOB_COUNT) @top_industries = @solr.facet_query('industry_id').take(Industry::TOP_JOB_COUNT)
@top_industries = solr.facet_query('industry_id').take(Industry::TOP_JOB_COUNT) @member = User.count
@resume = ApplyJob.count
@company = Company.count
suggest
end end
private private
def suggest
return unless user_signed_in? && current_user.industries?
industry_ids = current_user.fav_industries_ids
@suggest_jobs = get_jobs(@solr.suggest_jobs(industry_ids))
end
def solr
@solr = Solr.new(params)
end
def get_jobs(query) def get_jobs(query)
jobs_ids = query['response']['docs'].map { |j| j['job_id'] } jobs_ids = query['response']['docs'].map { |j| j['job_id'] }
Job.eager_load(:cities, :cities_jobs, :company).find(jobs_ids) Job.includes(:cities, :cities_jobs, :company).find(jobs_ids)
end end
end end
...@@ -16,12 +16,12 @@ module ApplicationHelper ...@@ -16,12 +16,12 @@ module ApplicationHelper
a = list.map do |item| a = list.map do |item|
case model case model
when :city when :city
link_to item.name, city_jobs_path(city_slug: item.slug), class: 'mx-1 text-decoration-none text-info' link_to item.name, city_jobs_path(city_slug: item.slug)
when :industry when :industry
link_to item.name, industry_jobs_path(industry_slug: item.slug), class: 'mx-1 text-decoration-none text-info' link_to item.name, industry_jobs_path(industry_slug: item.slug)
end end
end end
a.join('|').html_safe a.join(' | ').html_safe
end end
def view_search_result def view_search_result
......
module FavoriteIndustriesHelper
end
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
// that code so it'll be compiled. // that code so it'll be compiled.
//= require jquery //= require jquery
//= require jquery_ujs //= require jquery_ujs
//= require popper
//= require bootstrap
//= require turbolinks //= require turbolinks
//= require_tree . //= require_tree .
...@@ -17,7 +19,5 @@ Rails.start() ...@@ -17,7 +19,5 @@ Rails.start()
Turbolinks.start() Turbolinks.start()
ActiveStorage.start() ActiveStorage.start()
import "bootstrap"
window.bootstrap = require("bootstrap");
import "../stylesheets/application.scss";
import "./validation"; import "./validation";
import "./main";
(function ($) {
"use strict";
/*--
Commons Variables
-----------------------------------*/
var $window = $(window),
$body = $('body'),
$mainWrapper = $('.main-wrapper'),
$headerHeight = $('.header').outerHeight();
/*______________________________ */
/*--
Custom script to call Background
Image form html data attribute
-----------------------------------*/
$('[data-bg-image]').each(function () {
var $this = $(this),
$image = $this.data('bg-image');
$this.css('background-image', 'url(' + $image + ')');
});
/*--
Parallax
-----------------------------------*/
$('.bg-parallax').each(function () {
$(this).parallax("50%", 0.5);
})
/*--
Header Sticky
-----------------------------------*/
$window.on('scroll', function () {
if ($window.scrollTop() > 350) {
$('.header').addClass('is-sticky');
} else {
$('.header').removeClass('is-sticky');
}
});
/*--
Mobile OffCanvas Open & Close
-----------------------------------*/
function mobileOffCanvasToggle() {
var $offCanvas = $('#offcanvas'),
$offCanvasOverlay = $('.offcanvas-overlay');
$('.offcanvas-toggle').on('click', function () {
$offCanvas.addClass('open');
$offCanvasOverlay.fadeIn();
$body.addClass('offcanvas-open');
});
$('.offcanvas-close, .offcanvas-overlay').on('click', function () {
$offCanvas.removeClass('open');
$offCanvasOverlay.fadeOut();
$body.removeClass('offcanvas-open');
});
}
mobileOffCanvasToggle();
/*--
Off Canvas Menu
-----------------------------------*/
function mobileOffCanvasMenu() {
var $offCanvasNav = $('.offcanvas-menu'),
$offCanvasNavSubMenu = $offCanvasNav.find('.sub-menu');
/*Add Toggle Button With Off Canvas Sub Menu*/
$offCanvasNavSubMenu.parent().prepend('<span class="menu-expand"><i></i></span>');
/*Category Sub Menu Toggle*/
$offCanvasNav.on('click', 'li a, li .menu-expand', function (e) {
var $this = $(this);
if ($this.siblings('.sub-menu').length && ($this.attr('href') === '#' || $this.hasClass('menu-expand'))) {
e.preventDefault();
if ($this.siblings('ul:visible').length) {
$this.parent('li').removeClass('active');
$this.siblings('ul').slideUp();
$this.parent('li').find('li').removeClass('active');
$this.parent('li').find('ul:visible').slideUp();
} else {
$this.parent('li').addClass('active');
$this.closest('li').siblings('li').removeClass('active').find('li').removeClass('active');
$this.closest('li').siblings('li').find('ul:visible').slideUp();
$this.siblings('ul').slideDown();
}
}
});
}
mobileOffCanvasMenu();
/*--
Slick Slider Activation
-----------------------------------*/
// Company Slider
$('.company-slider').slick({
slidesToShow: 6,
slidesToScroll: 1,
arrows: true,
autoplay: true,
prevArrow: '<button class="slick-prev"><i class="fa fa-angle-left"></i></button>',
nextArrow: '<button class="slick-next"><i class="fa fa-angle-right"></i></button>',
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 5
}
}, {
breakpoint: 992,
settings: {
slidesToShow: 4
}
}, {
breakpoint: 767,
settings: {
slidesToShow: 3,
arrows: false
}
}, {
breakpoint: 480,
settings: {
slidesToShow: 2,
arrows: false
}
}]
});
// Job Category Slider
$('.job-category-slider').slick({
slidesToShow: 5,
slidesToScroll: 1,
arrows: true,
autoplay: true,
prevArrow: '<button class="slick-prev"><i class="fa fa-angle-left"></i></button>',
nextArrow: '<button class="slick-next"><i class="fa fa-angle-right"></i></button>',
responsive: [{
breakpoint: 1200,
settings: {
slidesToShow: 4
}
}, {
breakpoint: 992,
settings: {
slidesToShow: 3
}
}, {
breakpoint: 767,
settings: {
slidesToShow: 2,
arrows: false
}
}, {
breakpoint: 480,
settings: {
slidesToShow: 1
}
}]
});
// Testimonial Slider
$('.testimonial-slider').slick({
slidesToShow: 1,
slidesToScroll: 1,
arrows: true,
autoplay: true,
prevArrow: '<button class="slick-prev"><i class="fa fa-angle-left"></i></button>',
nextArrow: '<button class="slick-next"><i class="fa fa-angle-right"></i></button>',
responsive: [{
breakpoint: 767,
settings: {
slidesToShow: 1,
arrows: false
}
}]
});
// Blog Slider
$('.blog-slider').slick({
slidesToShow: 3,
slidesToScroll: 1,
arrows: false,
autoplay: true,
prevArrow: '<button class="slick-prev"><i class="fa fa-angle-left"></i></button>',
nextArrow: '<button class="slick-next"><i class="fa fa-angle-right"></i></button>',
responsive: [{
breakpoint: 992,
settings: {
slidesToShow: 2
}
}, {
breakpoint: 767,
settings: {
slidesToShow: 2,
arrows: false
}
}, {
breakpoint: 767,
settings: {
slidesToShow: 2,
arrows: false
}
}, {
breakpoint: 575,
settings: {
slidesToShow: 1
}
}]
});
/*--
Counter Up
-----------------------------------*/
$('.counter').counterUp({
time: 3000
});
/*--
Salary Range (Ion Range Slider)
-----------------------------------*/
$("#salary-range").ionRangeSlider({
type: "double",
min: 3000,
max: 25000,
step: 500,
from: 7000,
to: 15000,
grid: false,
});
/*--
Scroll Up
-----------------------------------*/
$.scrollUp({
scrollText: '<i class="fa fa-long-arrow-up"></i>',
});
})(jQuery);
class FavoriteIndustry < ApplicationRecord
belongs_to :user
belongs_to :industry
end
...@@ -2,6 +2,8 @@ class Industry < ApplicationRecord ...@@ -2,6 +2,8 @@ class Industry < ApplicationRecord
TOP_JOB_COUNT = 9 TOP_JOB_COUNT = 9
has_and_belongs_to_many :jobs has_and_belongs_to_many :jobs
has_many :favorite_industries, dependent: :destroy
validates :slug, presence: true, uniqueness: { case_sensitive: true } validates :slug, presence: true, uniqueness: { case_sensitive: true }
......
...@@ -14,4 +14,8 @@ class Job < ApplicationRecord ...@@ -14,4 +14,8 @@ class Job < ApplicationRecord
has_many :apply_jobs, dependent: :destroy has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs, dependent: :destroy has_many :history_jobs, dependent: :destroy
def self.top_views
includes(:cities, :cities_jobs, :company).order(views_count: :desc).limit(LATEST_JOBS_LIMIT)
end
end end
...@@ -7,6 +7,7 @@ class User < ApplicationRecord ...@@ -7,6 +7,7 @@ class User < ApplicationRecord
has_many :apply_jobs, dependent: :destroy has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs, dependent: :destroy has_many :history_jobs, dependent: :destroy
has_many :favorite_industries, dependent: :destroy
has_one_attached :cv has_one_attached :cv
...@@ -32,6 +33,20 @@ class User < ApplicationRecord ...@@ -32,6 +33,20 @@ class User < ApplicationRecord
@favorite_job_ids.include?(job.id) @favorite_job_ids.include?(job.id)
end end
def fav_industry?(industry_slug)
industry_id = Industry.find_by(slug: industry_slug).id
@fav_industry_ids ||= Set.new(favorite_industries.pluck(:industry_id))
@fav_industry_ids.include?(industry_id)
end
def industries?
favorite_industries.exists?
end
def fav_industries_ids
favorite_industries.pluck(:industry_id)
end
protected protected
def password_required? def password_required?
......
...@@ -62,7 +62,7 @@ class Solr ...@@ -62,7 +62,7 @@ class Solr
city_name = city.name city_name = city.name
q = "search:*#{@params[:search]}*" q = "search:*#{@params[:search]}*"
fq = if @params[:salary] fq = if @params[:salary].present?
["cities_name: \"#{escape_str(city_name)}\"", "min_salary: [#{@params[:salary]} TO *]"] ["cities_name: \"#{escape_str(city_name)}\"", "min_salary: [#{@params[:salary]} TO *]"]
else else
"cities_name: \"#{escape_str(city_name)}\"" "cities_name: \"#{escape_str(city_name)}\""
...@@ -78,7 +78,7 @@ class Solr ...@@ -78,7 +78,7 @@ class Solr
industry_name = industry.name industry_name = industry.name
q = "search:*#{@params[:search]}*" q = "search:*#{@params[:search]}*"
fq = if @params[:salary] fq = if @params[:salary].present?
["industries_name: \"#{escape_str(industry_name)}\"", "min_salary: [#{@params[:salary]} TO *]"] ["industries_name: \"#{escape_str(industry_name)}\"", "min_salary: [#{@params[:salary]} TO *]"]
else else
"industries_name: \"#{escape_str(industry_name)}\"" "industries_name: \"#{escape_str(industry_name)}\""
...@@ -87,6 +87,16 @@ class Solr ...@@ -87,6 +87,16 @@ class Solr
send_request(q, fq) send_request(q, fq)
end end
def suggest_jobs(arr)
parsed = arr.join(' ')
q = "industry_id: #{parsed}"
fq = []
facet = nil
sort = 'max_salary desc'
rows = 5
send_request(q, fq, facet, sort, rows)
end
def facet_query(facet_param) def facet_query(facet_param)
q = '*:*' q = '*:*'
fq = '*:*' fq = '*:*'
......
...@@ -2,88 +2,87 @@ ...@@ -2,88 +2,87 @@
- provide(:title, 'All applies jobs') - provide(:title, 'All applies jobs')
/ search / search
.container.mt-5 = render 'shared/page_heading', title: 'Applies jobs', url: history_jobs_path
= form_with(url: admin_applies_jobs_path, method: :get, local: true) do |f| .section.section-padding
.row.mb-2.form-group .container
.col-2 = form_with(url: admin_applies_jobs_path, method: :get, local: true) do |f|
= f.label :email, 'Email', class: 'form-label' .row.mb-2.form-group
.col-10 .col-2
= f.text_field :email, class: 'form-control', value: params[:email] = f.label :email, 'Email', class: 'form-label'
.col-10
.row.mb-2.form-group = f.text_field :email, class: 'form-control', value: params[:email]
.col-2
= f.label :city, 'City' .row.mb-2.form-group
.col-10 .col-2
= f.select :city, options_for_select(@city, selected: params[:city]), { include_blank: 'Select city' }, { class: 'form-select' } = f.label :city, 'City'
.row.mb-2.form-group .col-10
.col-2 = f.select :city, options_for_select(@city, selected: params[:city]), { include_blank: 'Select city' }, { class: 'form-select' }
= f.label :industry, 'Industry', class: 'form-label' .row.mb-2.form-group
.col-10 .col-2
= f.select :industry, options_for_select(@industry, selected: params[:industry]), { include_blank: 'Select industry' }, { class:'form-select' } = f.label :industry, 'Industry', class: 'form-label'
.col-10
= f.select :industry, options_for_select(@industry, selected: params[:industry]), { include_blank: 'Select industry' }, { class:'form-select' }
.row.mb-2.form-group .row.mb-2.form-group
.col-6 .col-6
.row .row
.col-4 .col-4
= f.label :date_start, 'From', class: 'form-label' = f.label :date_start, 'From', class: 'form-label'
.col-8 .col-8
= f.date_field :date_start, value: params[:date_start], class: 'form-control' = f.date_field :date_start, value: params[:date_start], class: 'form-control'
.col-6 .col-6
.row .row
.col-4 .col-4
= f.label :date_end, 'To', class: 'form-label' = f.label :date_end, 'To', class: 'form-label'
.col-8 .col-8
= f.date_field :date_end, value: params[:date_end], class: 'form-control' = f.date_field :date_end, value: params[:date_end], class: 'form-control'
.row .row
.col-6.d-flex.justify-content-center .col-6.d-flex.justify-content-center
= f.submit 'Search', name: 'search', class: 'btn btn-primary w-50 my-4 btn-height',data: { disable_with: false } = f.submit 'Search', name: 'search', class: 'btn btn-primary w-50 my-4 btn-height',data: { disable_with: false }
.col-6.d-flex.justify-content-center .col-6.d-flex.justify-content-center
= f.submit 'Export', name: 'csv',class: 'btn btn-primary w-50 my-4 btn-height',data: { disable_with: false } = f.submit 'Export', name: 'csv',class: 'btn btn-primary w-50 my-4 btn-height',data: { disable_with: false }
/result /result
.container .container.mb-3
h2.my-5.text-center .no-padding.d-flex.align-items-center.flex-column
| All applies jobs .page-info.p-2
.container = page_entries_info @apply_jobs
.no-padding.d-flex.align-items-center.flex-column .page-info.p-2
.page-info.p-2 = paginate @apply_jobs
= page_entries_info @apply_jobs .container
.page-info.p-2 - @apply_jobs.each do |apply|
= paginate @apply_jobs .apply-item
.container .apply-job-title
- @apply_jobs.each do |apply| = link_to apply.job.title, apply.job, class: 'job-title fs-3 text-decoration-none text-reset'
.apply-item .apply-user-name.text-secondary
.apply-job-title p.fw-bold
= link_to apply.job.title, apply.job, class: 'job-title fs-3 text-decoration-none text-reset' | Candidate Name:
.apply-user-name.text-secondary
p.fw-bold
| Candidate Name:
span.fw-normal.text-dark
= apply.user_name
.apply-cv
p.fw-bold.text-secondary
| Candidate' CV:
- if apply.cv.attached?
span.fw-normal
= link_to apply.cv.filename, rails_blob_path(apply.cv, disposition: "attachment")
- else
span.fw-normal.text-dark span.fw-normal.text-dark
= 'cv file not uploaded yet' = apply.user_name
.d-flex.align-items-center.justify-content-between .apply-cv
.apply-user-email
p.fw-bold.text-secondary p.fw-bold.text-secondary
| Candidate's Email: | Candidate' CV:
span.fw-normal.text-dark - if apply.cv.attached?
= apply.email span.fw-normal
.apply-date = link_to apply.cv.filename, rails_blob_path(apply.cv, disposition: "attachment")
p.fst-italic.text-secondary - else
| Applied at: span.fw-normal.text-dark
span.fw-normal.text-dark = 'cv file not uploaded yet'
= apply.created_at.strftime('%d/%m/%Y') .d-flex.align-items-center.justify-content-between
hr .apply-user-email
.container p.fw-bold.text-secondary
.no-padding.d-flex.align-items-center.flex-column | Candidate's Email:
.page-info.p-2 span.fw-normal.text-dark
= page_entries_info @apply_jobs = apply.email
.page-info.p-2 .apply-date
= paginate @apply_jobs p.fst-italic.text-secondary
| Applied at:
span.fw-normal.text-dark
= apply.created_at.strftime('%d/%m/%Y')
hr
.container
.no-padding.d-flex.align-items-center.flex-column
.page-info.p-2
= page_entries_info @apply_jobs
.page-info.p-2
= paginate @apply_jobs
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "admins/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>
<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>
<%= render "admins/shared/links" %>
- provide(:title, 'Resend confirmation instructions')
= render 'shared/page_heading', title: 'Resend'
.section.section-padding
.container
.row.justify-content-center
.col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= render "admins/shared/error_messages", resource: resource
.field
= f.label :email
br
= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email)
.actions
= f.submit "Resend confirmation instructions"
= render "admins/shared/links"
\ No newline at end of file
- provide(:title, 'Admin Forgot password') - provide(:title, 'Admin Forgot password')
= render 'shared/page_heading', title: 'Forgot password', url: login_path
.container .section.section-padding
.row.justify-content-center .container
.col-6 .row.justify-content-center
h2.text-center.my-5 .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
| Forgot password = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| = render 'admins/shared/error_messages', resource: resource
= render 'admins/shared/error_messages', resource: resource .field.row.form-group.mb-4
.field.row.form-group.mb-4 .col-lg-2.col-sm-2.col-12
.col-2 = f.label :email, class: 'form-label'
= f.label :email, class: 'form-label' .col-lg-10.col-sm-10.col-12
.col-10 = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' span.form-msg
span.form-msg - if devise_mapping.confirmable? && controller_name != 'confirmations'
- if devise_mapping.confirmable? && controller_name != 'confirmations' p
p = link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none' .actions.row.justify-content-end
.actions.row.justify-content-end .col-lg-10.col-12.d-flex.justify-content-around
.col-10.d-flex.justify-content-center = f.submit 'Confirm your email', class: 'btn btn-primary w-100 my-4', data: { disable_with: false }
= f.submit 'Confirm your email', class: 'btn btn-primary w-75 my-4', data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
......
- provide(:title, 'Admin Sign Up') - provide(:title, 'Admin Sign Up')
.container = render 'shared/page_heading', title: 'Sign up', url: new_admin_registration_path
.row.justify-content-center
.col-6 .section.section-padding
h2.text-center.my-5 .container
| Sign up .row.justify-content-center
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
= render 'users/shared/error_messages', resource: resource = form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
.field.row.form-group.mb-4 = render 'users/shared/error_messages', resource: resource
.col-2 .field.row.form-group.mb-4
= f.label :email, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :email, class: 'form-label'
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
.field.row.form-group.mb-4 span.form-msg
.col-2 .field.row.form-group.mb-4
= f.label :password, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :password, class: 'form-label'
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
.field.row.form-group.mb-4 span.form-msg
.col-2 .field.row.form-group.mb-4
= f.label :password_confirmation, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :password_confirmation, class: 'form-label'
= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2'
.actions span.form-msg
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5' .actions.row.justify-content-end
.col-lg-10.col-12.d-flex.justify-content-around
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
javascript: javascript:
Validator({ Validator({
......
- provide(:title, 'Log in') - provide(:title, 'Log in')
.container = render 'shared/page_heading', title: 'Admin Login', url: admin_login_path
.row.justify-content-center
.col-6 .section.section-padding
h2.text-center.my-5 .container
| Log in Admin .row.justify-content-center
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
.field.row.form-group.mb-4 = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.col-2 .field.row.form-group.mb-4
= f.label :email, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :email, class: 'form-label'
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
.field.row.form-group.mb-4 span.form-msg
.col-2 .field.row.form-group.mb-4
= f.label :password, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :password, class: 'form-label'
= f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2'
- if devise_mapping.rememberable? span.form-msg
.field - if devise_mapping.rememberable?
= f.check_box :remember_me .field
= f.label :remember_me, class: 'form-label mx-2' = f.check_box :remember_me
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' = f.label :remember_me, class: 'form-label mx-2'
= link_to 'Forgot password?', forgot_password_path, class: 'text-decoration-none' .d-flex.justify-content-between
.actions.row.justify-content-end - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
.col-10.d-flex.justify-content-around = link_to 'Forgot password?', new_admin_password_path, class: 'text-decoration-none'
= f.submit 'Log in', class: 'btn btn-primary w-25', data: { disable_with: false } = link_to 'Sign up', new_registration_path(resource_name), class: 'text-decoration-none'
= link_to 'Sign up', new_registration_path(resource_name), class: 'text-decoration-none w-25 btn btn-secondary'
.actions.row.justify-content-end
.col-lg-10.col-12.d-flex.justify-content-around
= f.submit 'Log in', class: 'btn btn-primary w-100', data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
......
.job-item / .job-item
.job-head.d-flex.align-items-center.justify-content-between / .job-head.d-flex.align-items-center.justify-content-between
= link_to applied_job.job.title, applied_job.job, class: 'job-title fs-3 text-decoration-none text-reset' / = link_to applied_job.job.title, applied_job.job, class: 'job-title fs-3 text-decoration-none text-reset'
- if user_signed_in? && current_user.favorite?(applied_job.job) / - if user_signed_in? && current_user.favorite?(applied_job.job)
= render 'shared/unfavorite', job_id: applied_job.job.id / = render 'shared/unfavorite', job_id: applied_job.job.id
- else / - else
= render 'shared/favorite', job_id: applied_job.job.id / = render 'shared/favorite', job_id: applied_job.job.id
.job-caption / .job-caption
= link_to applied_job.job.company.name, '#', class: 'job-company text-decoration-none text-secondary' / = link_to applied_job.job.company.name, '#', class: 'job-company text-decoration-none text-secondary'
p.job-salary.text-success / p.job-salary.text-success
| Salary: #{applied_job.job.salary} / | Salary: #{applied_job.job.salary}
ul.list-unstyled / ul.list-unstyled
= show_location(applied_job.job.cities) / = show_location(applied_job.job.cities)
.job-desc / .job-desc
= truncate(simple_format(applied_job.job.description), escape: false, length: 250) / = truncate(simple_format(applied_job.job.description), escape: false, length: 250)
.applied-at / .applied-at
/ strong Applied at:
/ = applied_job.updated_at.strftime('%d/%m/%Y')
/ hr.my-4
= link_to applied_job.job, class: 'job-list' do
.company-logo.col-auto
= image_tag('company-logo', width: '70')
.salary-type.col-auto.order-sm-3
span.salary-range
= applied_job.job.salary
span.badge.badge-success
= applied_job.job.job_type
.content.col
h6.title
= applied_job.job.title
ul.meta
li
strong.text-primary
= applied_job.job.company.name
li
i.fa.fa-map-marker
= show_location(applied_job.job.cities)
p.applied-at
strong Applied at: strong Applied at:
= applied_job.updated_at.strftime('%d/%m/%Y') = applied_job.updated_at.strftime('%d/%m/%Y')
hr.my-4
- provide(:title, 'Confirmation') - provide(:title, 'Confirmation')
.container = render 'shared/page_heading', title: 'Confirm', url: '#'
= render 'ribbon'
.container .section
h1.my-5.text-center .container
| Confirmation = render 'ribbon'
.col
= form_with(model: @apply, scope: :apply_job, url: done_job_path, local: true) do |f|
.row.mb-5
= f.hidden_field :job_id, value: @job.id
= f.hidden_field :blob_id, value: @blob.id
.col-2
= f.label :name, 'Full name:', class: 'form-label label'
.col-10
span.mx-2.label.form-control
= @apply.user_name
= f.hidden_field :user_name, value: @apply.user_name
.row.mb-5 .container
.col-2 .col
= f.label :email, 'Email:', class: 'form-label label' = form_with(model: @apply, scope: :apply_job, url: done_job_path, local: true) do |f|
.col-10
span.mx-2.label.form-control .row.mb-5
= @apply.email = f.hidden_field :job_id, value: @job.id
= f.hidden_field :email, value: @apply.email = f.hidden_field :blob_id, value: @blob.id
.col-2
.row.mb-5 = f.label :name, 'Full name:', class: 'form-label label'
.col-2 .col-10
= f.label :cv, 'Cv: ', class: 'form-label label' span.mx-2.label.form-control
.col-10 = @apply.user_name
span.form-control = f.hidden_field :user_name, value: @apply.user_name
= url_for(@apply.cv)
= link_to 'Edit', apply_job_path(job_id: @job.id), class: 'btn btn-secondary w-25 btn-height mr-5 my-5'
= f.submit 'Confirm', class: 'btn btn-primary w-25 btn-height mx-5 my-5' .row.mb-5
.col-2
= f.label :email, 'Email:', class: 'form-label label'
.col-10
span.mx-2.label.form-control
= @apply.email
= f.hidden_field :email, value: @apply.email
.row.mb-5
.col-2
= f.label :cv, 'Cv: ', class: 'form-label label'
.col-10
span
= url_for(@apply.cv)
= link_to 'Edit', apply_job_path(job_id: @job.id), class: 'btn btn-secondary w-25 btn-height mr-5 my-5'
= f.submit 'Confirm', class: 'btn btn-primary w-25 btn-height mx-5 my-5'
- provide(:title, 'Done') - provide(:title, 'Done')
.container = render 'shared/page_heading', title: 'Done', url: '#'
=render 'ribbon'
.container.text-center .section.py-5
h3.my-4 .container
| You have successfully applied for the #{@job.title} =render 'ribbon'
p Good luck! Thank you for using our service
= link_to 'Keep looking for another job', root_path .container.text-center
h3.my-4
| You have successfully applied for the #{@job.title}
p Good luck! Thank you for using our service
= link_to 'Keep looking for another job', root_path
- provide(:title, 'User Apply Jobs') - provide(:title, 'User Apply Jobs')
.container.py-5 = render 'shared/page_heading', title: 'APPlIED JOBS', url: apply_jobs_path
h1.text-center.my-job-label My Job
.no-padding.d-flex.align-items-center.flex-column .section.section-padding
.page-info.p-2 .container
= page_entries_info @jobs .job-list-toolbar
.page-info.p-2 .page-info.p-2
= paginate @jobs = page_entries_info @jobs
= render partial: "my_jobs", collection: @jobs, as: :applied_job .job-list-wrap
.no-padding.d-flex.align-items-center.flex-column = render partial: "my_jobs", collection: @jobs, as: :applied_job
.page-info.p-2 ul.pagination.pagination-center.mt-5
= page_entries_info @jobs = paginate @jobs
.page-info.p-2 \ No newline at end of file
= paginate @jobs
- provide(:title, 'Apply job') - provide(:title, 'Apply job')
.container = render 'shared/page_heading', title: 'Apply form', url: '#'
= render 'ribbon'
.container .section
h1.my-5.text-center .container.py-5
| Apply Form = render 'ribbon'
p.fs-5.fw-bold.mb-4.text-center .container
= @job.title h3.fs-5.fw-bold.mb-4.text-center
.col = @job.title
= form_with(model: @apply, url: confirm_job_path, local: true, id: 'apply-form') do |f| .col
= render 'shared/error_messages', object: f.object = form_with(model: @apply, url: confirm_job_path, local: true, id: 'apply-form') do |f|
.row.mb-5.form-group = render 'shared/error_messages', object: f.object
= f.hidden_field :job_id, value: @job.id .row.mb-5.form-group
.col-2 = f.hidden_field :job_id, value: @job.id
= f.label :user_name, 'Full name', class: 'form-label label' .col-2
.col-10 = f.label :user_name, 'Full name', class: 'form-label label'
= f.text_field :user_name, value: @apply.user_name || @current_user.name, class: 'form-control' .col-10
span.form-msg = f.text_field :user_name, value: @apply.user_name || @current_user.name, class: 'form-control'
.row.mb-5.form-group span.form-msg
.col-2 .row.mb-5.form-group
= f.label :email, class: 'form-label label' .col-2
.col-10 = f.label :email, class: 'form-label label'
= f.text_field :email, value: @apply.email || @current_user.email, class: 'form-control' .col-10
span.form-msg = f.text_field :email, value: @apply.email || @current_user.email, class: 'form-control'
.row.mb-5.form-group span.form-msg
/ - if @user.cv.attached? .row.mb-5.form-group
/ = url_for(@user.cv) / - if @user.cv.attached?
.col-2 / = url_for(@user.cv)
= f.label :cv, class: 'form-label label' .col-2
.col-10 = f.label :cv, class: 'form-label label'
= f.file_field :cv, files: @blob, accept: ApplyJob::ACCEPT_CONTENT_TYPE, class: 'form-control' .col-10
span.form-msg = f.file_field :cv, files: @blob, accept: ApplyJob::ACCEPT_CONTENT_TYPE
br span.form-msg
= f.submit 'Confirm', class: 'btn btn-primary w-25 my-4 btn-height',data: { disable_with: false } br
= f.submit 'Confirm', class: 'btn btn-primary w-25 my-4 btn-height',data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
......
- provide(:title, 'Cities')
= render 'shared/page_heading', title: 'Cities', url: cities_path
/region /region
.countries-list .section.section-padding
.container.py-5 .container
h2.mt-0 REGION .countries-list
hr.my-4 .container.py-5
.row h2.mt-0 REGION
- @regions.each do |region| hr.my-4
.col-lg-4.col-md-6.text-center .row
.mt-5 - @regions.each do |region|
h3.h4.mb-2.text-white.see-more-text= link_to region.upcase, anchor: region .col-lg-4.col-md-6.text-center
// cities list .mt-5
.cities-list h3.mb-2.text-primary.see-more-text= link_to region.upcase, anchor: region
.container // cities list
- @job_quantity_by_region.each do |region, city_job_count| .cities-list
.countries-job-list id=region .container
.container-fullwidth.py-5 - @job_quantity_by_region.each do |region, city_job_count|
h2.mt-0 .countries-job-list id=region
= region.upcase .container-fullwidth.py-5
hr.my-4 h2.mt-0
.row = region.upcase
- city_job_count.each do |city| hr.my-4
.col-lg-4.col-md-6.text-center .row
.mt-5 - city_job_count.each do |city|
.city-item .col-lg-4.col-md-6.col-12.text-center
h3.h4.mb-2.see-more-text= link_to city[0], city_jobs_path(city_slug: city[1]) , class:'text-decoration-none fw-normal text-reset' .mt-5
p.text-muted.mb-0= pluralize(city[2], 'job') .city-item
\ No newline at end of file h3.h4.mb-2.see-more-text= link_to city[0], city_jobs_path(city_slug: city[1]) , class:'text-decoration-none fw-normal text-reset'
p.text-muted.mb-0= pluralize(city[2], 'job')
\ No newline at end of file
div id="favorite-industry-#{industry_id}"
= button_to favorite_industries_path(industry_id: industry_id, format: :js),
method: :post,
remote: true,
class: 'btn' do
i.fa.fa-heart-o.mr-1
\ No newline at end of file
div id="unfavorite-industry-#{industry_id}"
= button_to favorite_industry_path(current_user, industry_id: industry_id, format: :js),
method: :delete,
remote: true,
class: 'btn' do
i.fa.fa-heart.mr-1
\ No newline at end of file
$("#favorite-industry-<%= @industry.id %>").html("<%= escape_javascript(render('unfavorite', industry_id: @industry.id)) %>");
$("#unfavorite-industry-<%= @industry.id %>").html("<%= escape_javascript(render('favorite', industry_id: @industry.id)) %>");
- provide(:title, 'History page') - provide(:title, 'History page')
= render 'shared/page_heading', title: 'FAVORITE', url: favorite_jobs_path
- if @favorite_jobs.empty? - if @favorite_jobs.empty?
h2 No jobs in your history .section.section-padding
.container.text-center
h2 You have not applied for any job yet
= link_to 'See more jobs', jobs_path, class: 'btn btn-primary m-3'
- else - else
= render partial: 'shared/jobs_list_index', object: @favorite_jobs, as: 'jobs' = render partial: 'shared/jobs_list_index', object: @favorite_jobs, as: 'jobs'
- provide(:title, 'History page') - provide(:title, 'History page')
= render 'shared/page_heading', title: 'HISTORY', url: history_jobs_path
- if @history_jobs.empty? - if @history_jobs.empty?
h2 No jobs in your history .section.section-padding
.container.text-center
h2 No jobs in your history
- else - else
= render partial: 'shared/jobs_list_index', object: @history_jobs, as: 'jobs' = render partial: 'shared/jobs_list_index', object: @history_jobs, as: 'jobs'
.countries-list - provide(:title, 'Industries')
.container.py-5
h2.mt-0 INDUSTRIES = render 'shared/page_heading', title: 'INDUSTRIES', url: industries_path
hr.my-4
.section.section-padding
.container
#info-box.row #info-box.row
- @job_quantity_by_industry.each do |industry| - @job_quantity_by_industry.each do |industry|
.col-lg-6.col-md-6.text-center .col-lg-6.col-sm-6.col-12.text-center
.mt-5 .mt-5
h3.h4.mb-2.see-more-text= link_to industry[0], industry_jobs_path(industry_slug: industry[1]) , class:'text-decoration-none fw-normal text-reset' .row
p.text-muted.mb-0= pluralize(industry[2], 'job') .col-10
h5.mb-2.see-more-text= link_to industry[0], industry_jobs_path(industry_slug: industry[1]) , class:'text-decoration-none fw-normal text-reset'
p.text-muted.mb-0= pluralize(industry[2], 'job')
.col-2
- if user_signed_in? && current_user.fav_industry?(industry[1])
= render 'favorite_industries/unfavorite', industry_id: Industry.find_by(slug: industry[1]).id
- else
= render 'favorite_industries/favorite', industry_id: Industry.find_by(slug: industry[1]).id
hr.divider.my-4 hr.divider.my-4
/ h3.h4.mb-2.see-more-text= link_to industry[0], industry_jobs_path(industry_slug: industry[1]) , class:'text-decoration-none fw-normal text-reset'
/ p.text-muted.mb-0= pluralize(industry[2], 'job')
/ hr.divider.my-4
- provide(:title, 'Job list page') - provide(:title, 'Job list page')
/ search box / search box
= render 'shared/page_heading', title: 'Jobs', url: jobs_path, name: @name
/ .page-heading-section.section.bg-parallax[data-bg-image="assets/images/bg/bg-1.jpg" data-overlay="50"]
/ .container
/ .page-heading-content.text-center
/ h3.title
/ | Browse Jobs
/ ol.breadcrumb
/ li.breadcrumb-item
/ = link_to 'Home', root_path
/ li.breadcrumb-item.active
/ = link_to 'Jobs', jobs_path
/ - if params[:city_slug] || params[:industry_slug]
/ li.breadcrumb-item.active
/ = @name
= render 'shared/search' = render 'shared/search'
.container .section.section-padding
h3
= view_search_result
hr.my-4
.no-padding.d-flex.align-items-center.flex-column
.page-info.p-2
= page_entries_info @jobs
.page-info.p-2
= paginate @jobs
.container
.container .container
- @jobs.each do |job| h3
/ job = view_search_result
.job-item .job-list-toolbar
.job-head.d-flex.align-items-center.justify-content-between .page-info.p-2
= link_to job.title, job, class: 'job-title fs-3 text-decoration-none text-reset' = page_entries_info @jobs
- if user_signed_in? && current_user.favorite?(job) .job-list-wrap
= render 'shared/unfavorite', job_id: job.id - @jobs.each do |job|
- else = link_to job, class: 'job-list' do
= render 'shared/favorite', job_id: job.id .company-logo.col-auto
.job-caption = image_tag('company-logo', width: '120')
= link_to job.company.name, '#', class: 'job-company text-decoration-none text-secondary' .salary-type.col-auto.order-sm-3
p.job-salary.text-success span.salary-range
| Salary: #{job.salary} = job.salary
ul.list-unstyled span.badge.badge-success
= show_location(job.cities) = job.job_type
.job-desc .content.col
= truncate(simple_format(job.description), escape: false, length: 250) h6.title
hr.my-4 = job.title
.no-padding.d-flex.align-items-center.flex-column ul.meta
.page-info.p-2 li
= page_entries_info @jobs strong.text-primary
.page-info.p-2 = job.company.name
= paginate @jobs li
\ No newline at end of file i.fa.fa-map-marker
- city_list = job.cities
= show_location(job.cities)
/ p
/ = truncate(simple_format(job.description), escape: false, length: 150)
ul.pagination.pagination-center.mt-5
= paginate @jobs
/ .section.section-padding
/ .container
/ h3
/ = view_search_result
/ hr.my-4
/ .no-padding.d-flex.align-items-center.flex-column
/ .page-info.p-2
/ = page_entries_info @jobs
/ .page-info.p-2
/ = paginate @jobs
/ .
/ - @jobs.each do |job|
/ / job
/ .job-item
/ .job-head.d-flex.align-items-center.justify-content-between
/ = link_to job.title, job, class: 'job-title fs-3 text-decoration-none text-reset'
/ - if user_signed_in? && current_user.favorite?(job)
/ = render 'shared/unfavorite', job_id: job.id
/ - else
/ = render 'shared/favorite', job_id: job.id
/ .job-caption
/ = link_to job.company.name, '#', class: 'job-company text-decoration-none text-secondary'
/ p.job-salary.text-success
/ | Salary: #{job.salary}
/ ul.list-unstyled
/ = show_location(job.cities)
/ .job-desc
/ = truncate(simple_format(job.description), escape: false, length: 250)
/ hr.my-4
/ .no-padding.d-flex.align-items-center.flex-column
/ .page-info.p-2
/ = page_entries_info @jobs
/ .page-info.p-2
/ = paginate @jobs
\ No newline at end of file
...@@ -2,90 +2,200 @@ ruby: ...@@ -2,90 +2,200 @@ ruby:
city_list = @job.cities city_list = @job.cities
industry_list = @job.industries industry_list = @job.industries
/ html .page-heading-section.section.bg-parallax[data-bg-image="assets/images/bg/bg-1.jpg" data-overlay="50"]
.container.my-5 .container
/ breadcrumb .page-heading-content.text-center
.breadcrumb h3.title
= link_to 'Home', root_path, class: 'text-decoration-none text-info'
span.mx-1 >
.text-info
= show_breadcrumb(city_list, :city)
span.mx-1 >
.text-info
= show_breadcrumb(industry_list, :industry)
span.mx-1 >
= @job.title
hr.my-4
/ job details
.job-detail.my5
.job-apply.d-flex.align-items-center.justify-content-between
h2.align-items-start
= @job.title = @job.title
= link_to 'Apply for this job', apply_job_path(job_id: @job.id), class: 'btn btn-primary' ol.breadcrumb
p.text-secondary li.breadcrumb-item
= @job.company.name = link_to 'Home', root_path
.row.bg-light li.breadcrumb-item
.col-4 = show_breadcrumb(city_list, :city)
ul.list-unstyled li.breadcrumb-item
li = show_breadcrumb(industry_list, :industry)
strong.d-block li.breadcrumb-item.active
| Location = @job.title
p .section.section-padding
= show_location(city_list) .container
li .row.mb-n5
strong .col-lg-8.col-12.mb-5.pr-lg-5
| Salary .job-list-details
p.text-success .job-details-head.row.mx-0
= @job.salary .company-logo.col-auto
.col-4 = image_tag('company-logo', width: 120)
ul.list-unstyled .salary-type.col-auto.order-sm-3
li span.salary-range
strong = @job.salary
| Type span.badge.badge-success
p = @job.job_type
= @job.job_type .content.col
li h5.title
strong = @job.title
| Position ul.meta
p li
= @job.position strong.text-primary
.col-4 = @job.company.name
ul.list-unstyled li
li i.fa.fa-map-marker
strong = show_location(city_list)
| Experience .job-details-body
p h6.mb-3
= @job.experience | Job Description
li = @job.description.html_safe
strong
| Expiration date h6.mb-3.mt-4
p | Requirement
= @job.expiration_date.strftime('%d/%m/%Y') = @job.requirement.html_safe
.job-benefits.my-4
h3 h6.mb-3.mt-4
| Benefits | Benefits
.row ul
- @job.benefit.split('---').each do |benefit| - @job.benefit.split('---').each do |benefit|
li.list-unstyled.col-4.text-secondary li.list-unstyled.col-4.text-secondary
= benefit = benefit
.job-desc.my-4 h6.mb-3.mt-4
h3 | Other info
| Description ul
= @job.description.html_safe - @job.other_info.split('---').each do |info|
.job-req.my-4 li.text-secondary
h3 = info
| Requirement
= @job.requirement.html_safe .col-lg-4.col-12.mb-5
.job-info.my-4 .sidebar-wrap
h3 .sidebar-widget
| Other info .inner
- @job.other_info.split('---').each do |info| .row.m-n2
li.text-secondary .col-xl-auto.col-lg-12.col-sm-auto.col-12.p-2
= info / a.d-block.btn.btn-outline-secondary[href="#"]
.job-apply.d-flex.align-items-center.justify-content-between / i.fa.fa-heart-o.mr-1
= link_to 'Apply for this job', apply_job_path(job_id: @job.id), class: 'btn btn-primary' / | Save Job
- if user_signed_in? && current_user.favorite?(@job)
= render 'shared/unfavorite', job_id: @job.id - if user_signed_in? && current_user.favorite?(@job)
- else = render 'shared/unfavorite', job_id: @job.id
= render 'shared/favorite', job_id: @job.id - else
= render 'shared/favorite', job_id: @job.id
.col-xl-auto.col-lg-12.col-sm-auto.col-12.p-2
= link_to 'Apply now', apply_job_path(job_id: @job.id), class: 'd-block btn btn-primary'
.sidebar-widget
.inner
h6.title
| Job Overview
ul.job-overview.list-unstyled
li
strong
| Published on:
= @job.created_at.strftime('%d/%m/%Y')
li
strong
| Experience:
= @job.experience
li
strong
| Type:
= @job.job_type
li
strong
| Position:
= @job.position
li
strong
| Job Location:
= show_location(city_list)
li
strong
| Salary:
= @job.salary
li
strong
| Application Deadline:
= @job.expiration_date.strftime('%d/%m/%Y')
/ / html
/ .container.my-5
/ / breadcrumb
/ .breadcrumb
/ = link_to 'Home', root_path, class: 'text-decoration-none text-info'
/ span.mx-1 >
/ .text-info
/ = show_breadcrumb(city_list, :city)
/ span.mx-1 >
/ .text-info
/ = show_breadcrumb(industry_list, :industry)
/ span.mx-1 >
/ = @job.title
/ hr.my-4
/ / job details
/ .job-detail.my5
/ .job-apply.d-flex.align-items-center.justify-content-between
/ h2.align-items-start
/ = @job.title
/ = link_to 'Apply for this job', apply_job_path(job_id: @job.id), class: 'btn btn-primary'
/ p.text-secondary
/ = @job.company.name
/ .row.bg-light
/ .col-4
/ ul.list-unstyled
/ li
/ strong.d-block
/ | Location
/ p
/ = show_location(city_list)
/ li
/ strong
/ | Salary
/ p.text-success
/ = @job.salary
/ .col-4
/ ul.list-unstyled
/ li
/ strong
/ | Type
/ p
/ = @job.job_type
/ li
/ strong
/ | Position
/ p
/ = @job.position
/ .col-4
/ ul.list-unstyled
/ li
/ strong
/ | Experience
/ p
/ = @job.experience
/ li
/ strong
/ | Expiration date
/ p
/ = @job.expiration_date.strftime('%d/%m/%Y')
/ .job-benefits.my-4
/ h3
/ | Benefits
/ .row
/ - @job.benefit.split('---').each do |benefit|
/ li.list-unstyled.col-4.text-secondary
/ = benefit
/ .job-desc.my-4
/ h3
/ | Description
/ = @job.description.html_safe
/ .job-req.my-4
/ h3
/ | Requirement
/ = @job.requirement.html_safe
/ .job-info.my-4
/ h3
/ | Other info
/ - @job.other_info.split('---').each do |info|
/ li.text-secondary
/ = info
/ .job-apply.d-flex.align-items-center.justify-content-between
/ = link_to 'Apply for this job', apply_job_path(job_id: @job.id), class: 'btn btn-primary'
/ - if user_signed_in? && current_user.favorite?(@job)
/ = render 'shared/unfavorite', job_id: @job.id
/ - else
/ = render 'shared/favorite', job_id: @job.id
footer.footer / footer.footer
small / small
| The / | The
= link_to 'VenJob', root_path / = link_to 'VenJob', root_path
| by Mai Hoàng Thái Hà / | by Mai Hoàng Thái Hà
nav / nav
ul / ul
li / li
= link_to 'About', '#' / = link_to 'About', '#'
li / li
= link_to 'Contact', '#' / = link_to 'Contact', '#'
\ No newline at end of file
.footer-top-section.section
.container
.footer-widget-wrap.row
.col-lg-3.col-sm-6.col-12
.footer-widget
.footer-widget-about
= link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'),
- root_path
p
| Lorem ipsum dolor sit amet consecte tur adipisicing elit. Maiores officiis quod quo id inventore quis.
ul.footer-socail
li
a[href="#"]
i.fa.fa-facebook
li
a[href="#"]
i.fa.fa-twitter
li
a[href="#"]
i.fa.fa-linkedin
li
a[href="#"]
i.fa.fa-pinterest-p
.col-lg-3.col-sm-6.col-12
.footer-widget
h6.title
| Column 1
.footer-widget-link
ul
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
.col-lg-3.col-sm-6.col-12
.footer-widget
h6.title
| Column 2
.footer-widget-link
ul
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
li
= link_to 'Item link', '#'
.col-lg-3.col-sm-6.col-12
.footer-widget
h6.title
| Newsletter
.footer-widget-newsletter
p
| Lorem ipsum dolor sit amet consecte tur adipisicing elit. Maiores officiis quod quo id inventore quis.
form#mc-form.mc-form
input#mc-email[autocomplete="off" type="email" placeholder="Enter your e-mail address"]
button#mc-submit.btn
i.fa.fa-envelope-o
.mailchimp-alerts.text-centre
.mailchimp-submitting
.mailchimp-success.text-success
.mailchimp-error.text-danger
.footer-bottom-section.section
.container
.row
.col-12
p.footer-copyright.text-center
| This is a sample website. Some functions won't work
header.navbar.navbar-fixed-top.navbar-inverse / header.navbar.navbar-fixed-top.navbar-inverse
.container / .container
= link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'), / = link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'),
- root_path / - root_path
nav / nav
ul.nav.navbar-nav.navbar-right.text-light / ul.nav.navbar-nav.navbar-right.text-light
- if user_signed_in? / - if user_signed_in?
li / li
= link_to "Apply jobs", apply_jobs_path / = link_to "Apply jobs", apply_jobs_path
li / li
= link_to "History", history_jobs_path / = link_to "History", history_jobs_path
li / li
= link_to "Favorite", favorite_jobs_path / = link_to "Favorite", favorite_jobs_path
li / li
= link_to "Profile", user_profile_path / = link_to "Profile", user_profile_path
li / li
= link_to "Log out", destroy_user_session_path, method: :delete / = link_to "Log out", destroy_user_session_path, method: :delete
- elsif admin_signed_in? / - elsif admin_signed_in?
li / li
= link_to "Applies job", admin_applies_jobs_path / = link_to "Applies job", admin_applies_jobs_path
li / li
= link_to "Profile", '#' / = link_to "Profile", '#'
li / li
= link_to "Log out", destroy_admin_session_path, method: :delete / = link_to "Log out", destroy_admin_session_path, method: :delete
- else / - else
li li
= link_to "Admin", admin_login_path = link_to "Admin", admin_login_path
li li
= link_to "Log in", login_path = link_to "Log in", login_path
li li
= link_to "Sign up", signup_path = link_to "Sign up", signup_path
\ No newline at end of file
header.header
.container
.row.justify-content-between.align-items-center
.col
.header-logo
= link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'),
- root_path
.col-auto.d-lg-none.d-flex.align-items-center
button.offcanvas-toggle
span
- unless user_signed_in? || admin_signed_in?
.header-links.col-auto.order-lg-3
= link_to "Log in", login_path
span or
= link_to "Sign up", signup_path
span |
= link_to "Admin", admin_login_path
nav#main-menu.main-menu.col-lg-auto.order-lg-2
ul
li.has-children
= link_to 'Home', root_path
li.has-children
= link_to 'All jobs', jobs_path
li.has-children
= link_to 'Industries', industries_path
li.has-children
= link_to 'Cities', cities_path
- if admin_signed_in?
li
= link_to 'Admin', '#'
ul.sub-menu
li.has-children
= link_to "Applies job", admin_applies_jobs_path
hr
li.has-children
= button_to "Sign out", destroy_admin_session_path, class: 'logout', method: :delete
- if user_signed_in?
li
= link_to "Profile", user_profile_path
ul.sub-menu
li.has-children
= link_to "Apply jobs", apply_jobs_path
li.has-children
= link_to "History", history_jobs_path
li.has-children
= link_to "Favorite", favorite_jobs_path
li.has-children
= link_to "Profile", user_profile_path
hr
li.has-children
= button_to "Log out", destroy_user_session_path, class: 'logout', method: :delete
#offcanvas.offcanvas-section
button.offcanvas-close[data-target="#offcanvas"]
| ×
.offcanvas-wrap
.inner
- unless user_signed_in? || admin_signed_in?
.offcanvas-user
= link_to "Log in", login_path
span or
= link_to "Sign up", signup_path
.offcanvas-menu
nav
ul
li.has-children
= link_to 'Home', root_path
li
= link_to 'Jobs', jobs_path
ul.sub-menu
li
= link_to 'Industries', industries_path
li
= link_to 'Cities', cities_path
li
= link_to 'Contact', '#'
- if user_signed_in?
li
= link_to current_user.name, user_profile_path
ul.sub-menu
li
= link_to 'Edit account', edit_profile_path
li
= link_to 'Favorited', favorite_jobs_path
li
= link_to 'History', history_jobs_path
li
= link_to 'Applied', apply_jobs_path
li
= link_to "Log out", destroy_user_session_path, method: :delete
.offcanvas-overlay
...@@ -12,8 +12,13 @@ html ...@@ -12,8 +12,13 @@ html
= yield(:head) = yield(:head)
body body
= render 'layouts/header' = render 'layouts/header'
.container-fluid style ="min-height:80vh;" .flash
- flash.each do |message_type, message| - flash.each do |message_type, message|
div class=("text-center alert alert-#{message_type}") = message div class=("m-0 text-center alert alert-#{message_type}")
= yield = message
= render 'layouts/footer' .text-center
\ No newline at end of file a.btn-close close
= yield
= render 'layouts/footer'
= javascript_pack_tag 'main'
div id="favorite-#{job_id}" div id="favorite-#{job_id}"
= link_to favorite_jobs_path(job_id: job_id, format: :js), = button_to favorite_jobs_path(job_id: job_id, format: :js),
method: :post, method: :post,
remote: true, remote: true,
class: 'btn btn-primary' class: 'd-block btn btn-outline-secondary' do
| Favorite i.fa.fa-heart-o.mr-1
| Favorite
/ = form_with(model: @favorite_job, url: favorite_jobs_path(job_id: job_id), id: "favorite-#{job_id}", remote: true) do |f|
/ = f.submit 'Favorite', class: 'd-block btn btn-outline-secondary'
.container.py-5 .section.section-padding
.no-padding.d-flex.align-items-center.flex-column .container
.page-info.p-2 .job-list-toolbar
= page_entries_info jobs .page-info.p-2
.page-info.p-2 = page_entries_info jobs
= paginate jobs .job-list-wrap
.container = form_with(url: apply_job_path, method: :get) do |f|
= form_with(url: apply_job_path, method: :get) do |f| - jobs.each do |item|
- jobs.each do |item| .row
.row .col-2.job-check.align-self-center
.col-1.job-check.align-self-center = f.radio_button :job_id, item.job.id, class: 'btn-check', id: "option-#{item.job.id}"
= f.radio_button :job_id, item.job.id, class: 'btn-check', id: "option-#{item.job.id}" = f.label 'Choose', class: 'btn btn-outline-primary', for: "option-#{item.job.id}"
= f.label 'Choose', class: 'btn btn-outline-primary', for: "option-#{item.job.id}" .col-10
.job-item.col-10 = link_to item.job, class: 'job-list' do
.job-head .company-logo.col-auto
= link_to item.job.title, item.job, class: 'job-title fs-3 text-decoration-none text-reset' = image_tag('company-logo', width: '120')
.job-caption .salary-type.col-auto.order-sm-3
= link_to item.job.company.name, '#', class: 'job-company text-decoration-none text-secondary' span.salary-range
p.job-salary.text-success = item.job.salary
| Salary: #{item.job.salary} span.badge.badge-success
ul.list-unstyled = item.job.job_type
= show_location(item.job.cities) .content.col
.job-desc h6.title
= truncate(simple_format(item.job.description), escape: false, length: 250) = item.job.title
.job-fav.col-1 ul.meta
- if user_signed_in? && current_user.favorite?(item.job) li
= render 'shared/unfavorite', job_id: item.job.id strong.text-primary
- else = item.job.company.name
= render 'shared/favorite', job_id: item.job.id li
hr.my-4 i.fa.fa-map-marker
.d-flex.justify-content-center - city_list = item.job.cities
= f.submit 'Apply job', class: 'btn btn-primary w-50' = show_location(item.job.cities)
.no-padding.d-flex.align-items-center.flex-column .d-flex.justify-content-center.my-5
.page-info.p-2 = f.submit 'Apply job', class: 'btn btn-primary w-50'
= page_entries_info jobs ul.pagination.pagination-center.mt-5
.page-info.p-2 = paginate jobs
= paginate jobs
/ .container.py-5
/ .no-padding.d-flex.align-items-center.flex-column
/ .page-info.p-2
/ = page_entries_info jobs
/ .page-info.p-2
/ = paginate jobs
/ .container
/ = form_with(url: apply_job_path, method: :get) do |f|
/ - jobs.each do |item|
/ .row
/ .col-1.job-check.align-self-center
/ = f.radio_button :job_id, item.job.id, class: 'btn-check', id: "option-#{item.job.id}"
/ = f.label 'Choose', class: 'btn btn-outline-primary', for: "option-#{item.job.id}"
/ .job-item.col-10
/ .job-head
/ = link_to item.job.title, item.job, class: 'job-title fs-3 text-decoration-none text-reset'
/ .job-caption
/ = link_to item.job.company.name, '#', class: 'job-company text-decoration-none text-secondary'
/ p.job-salary.text-success
/ | Salary: #{item.job.salary}
/ ul.list-unstyled
/ = show_location(item.job.cities)
/ .job-desc
/ = truncate(simple_format(item.job.description), escape: false, length: 250)
/ .job-fav.col-1
/ - if user_signed_in? && current_user.favorite?(item.job)
/ = render 'shared/unfavorite', job_id: item.job.id
/ - else
/ = render 'shared/favorite', job_id: item.job.id
/ hr.my-4
/ .d-flex.justify-content-center
/ = f.submit 'Apply job', class: 'btn btn-primary w-50'
/ .no-padding.d-flex.align-items-center.flex-column
/ .page-info.p-2
/ = page_entries_info jobs
/ .page-info.p-2
/ = paginate jobs
.page-heading-section.section.bg-parallax[data-bg-image="assets/banner-4.jpg" data-overlay="50"]
.container
.page-heading-content.text-center
h3.title
= title
ol.breadcrumb
li.breadcrumb-item
= link_to 'Home', root_path
li.breadcrumb-item.active
= link_to title, url: '#'
- if params[:city_slug] || params[:industry_slug]
li.breadcrumb-item.active
= name
\ No newline at end of file
.search.text-center.my-5 .job-search-section.section
.container .container
-if params[:city_slug] .job-search-wrap
= form_tag(city_jobs_path(city_slug: params[:city_slug]), method: :get, class: "form-inline") do .job-search-form
.row -if params[:city_slug]
.col-md-8.mb-md-0.no-padding = form_tag(city_jobs_path(city_slug: params[:city_slug]), method: :get) do
= search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)', class: 'form-control rounded-left no-border-radius bg-light h-100' .row.mb-n4
.col-md-2.mb-md-0.no-padding .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
= select_tag(:salary, = search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)'
options_for_select( @salary_range.collect {|s| [vnd_format(s), s]}, .col-lg-3.col-sm-6.col-12.flex-grow-1.mb-4
params[:salary] ), = select_tag(:salary,
class:"form-select bg-light h-100") options_for_select( @salary_range.collect {|s| [vnd_format(s), s]},
.col-md-2.mb-md-0.no-padding params[:salary] ),
= submit_tag "Search", class: "h-100 w-100 btn btn-block btn-lg btn-info" include_blank: 'Select salary')
.col-lg-3.col-sm-6.col-12.flex-grow-1.mb-4
-elsif params[:industry_slug] = submit_tag "Search", class: "btn btn-primary"
= form_tag(industry_jobs_path(industry_slug: params[:industry_slug]), method: :get, class: "form-inline") do -elsif params[:industry_slug]
.row = form_tag(industry_jobs_path(industry_slug: params[:industry_slug]), method: :get) do
.col-md-8.mb-md-0.no-padding .row.mb-n4
= search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)', class: 'form-control rounded-left no-border-radius bg-light h-100' .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
.col-md-2.mb-md-0.no-padding = search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)'
= select_tag(:salary, .col-lg-3.col-sm-6.col-12.flex-grow-1.mb-4
options_for_select( @salary_range.collect {|s| [vnd_format(s), s]}, = select_tag(:salary,
params[:salary] ), options_for_select( @salary_range.collect {|s| [vnd_format(s), s]},
class:"form-select bg-light h-100") params[:salary] ),
.col-md-2.mb-md-0.no-padding include_blank: 'Select salary')
= submit_tag "Search", class: "h-100 w-100 btn btn-block btn-lg btn-info" .col-lg-3.col-sm-6.col-12.flex-grow-1.mb-4
= submit_tag "Search", class: "btn btn-primary"
- else - else
= form_tag(jobs_path, method: :get, class: "form-inline") do = form_tag(jobs_path, method: :get) do
.row .row.mb-n4
.col-md-4.mb-md-0.no-padding .col-lg-4.col-sm-6.col-12.flex-grow-1.mb-4
= search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)', class: 'form-control rounded-left no-border-radius bg-light h-100' = search_field_tag :search, params[:search], placeholder: 'Find a job (name, company, position)'
.col-md-2.mb-md-0.no-padding .col-lg-2.col-sm-6.col-12.flex-grow-1.mb-4
= select_tag(:city, = select_tag(:city,
options_for_select( @city_slug_list, options_for_select( @city_slug_list,
params[:city] ), params[:city] ),
include_blank: 'Select city', include_blank: 'Select city')
class:"form-select bg-light h-100") .col-lg-2.col-sm-6.col-12.flex-grow-1.mb-4
.col-md-2.mb-md-0.no-padding = select_tag(:industry,
= select_tag(:industry, options_for_select( @industry_slug_list,
options_for_select( @industry_slug_list, params[:industry] ),
params[:industry] ), include_blank: 'Select city')
include_blank: 'Select city', .col-lg-2.col-sm-6.col-12.flex-grow-1.mb-4
class:"form-select bg-light h-100") = select_tag(:salary,
.col-md-2.mb-md-0.no-padding options_for_select( @salary_range.collect {|s| [vnd_format(s), s]},
= select_tag(:salary, params[:salary] ),
options_for_select( @salary_range.collect {|s| [vnd_format(s), s]}, include_blank: 'Select salary')
params[:salary] ),
include_blank: 'Select salary', .col-lg-2.col-sm-12.col-12.flex-grow-1.mb-4
class:"form-select bg-light h-100") = submit_tag "Search", class: "btn btn-primary"
.col-md-2.mb-md-0.no-padding
= submit_tag "Search", class: "h-100 w-100 btn btn-block btn-lg btn-info"
div id="unfavorite-#{job_id}" div id="unfavorite-#{job_id}"
= link_to favorite_job_path(current_user, job_id: job_id, format: :js), = button_to favorite_job_path(current_user, job_id: job_id, format: :js),
method: :delete, method: :delete,
remote: true, remote: true,
class: 'btn btn-secondary' class: 'btn btn-secondary'
| UnFavorite | UnFavorite
/ = form_with(model: @favorite_job, url: favorite_job_path(current_user, job_id: job_id), id: "unfavorite-#{job_id}", method: :delete, remote: true) do |f|
/ = f.submit 'UnFavorite', class: 'btn btn-secondary'
.section.section-padding
.container
.section-title
h2.title
= title
p
= desc
.job-list-wrap
- jobs.each do |job|
= link_to job, class: 'job-list' do
.company-logo.col-auto
= image_tag('company-logo', width: '70', height: '70')
.salary-type.col-auto.order-sm-3
span.salary-range
= job.salary
span.badge.badge-success
= job.job_type
.content.col
h6.title
= job.title
ul.meta
li
strong.text-primary
= job.company.name
li
i.fa.fa-map-marker
- city_list = job.cities
= show_location(job.cities)
.text-center.mt-4.mt-lg-5
= link_to 'View All Jobs', jobs_path , class: 'btn btn-primary'
- provide(:title, 'Home page') - provide(:title, 'Home page')
/ search box
.container / banner
.banner.d-flex.justify-content-center.align-items-center .slider-section.section
.row .slide-item.bg-parallax[data-bg-image="assets/banner-1" data-overlay="50"]
.col .container
h2.text-white .slider-content.text-center
| Total: #{pluralize(@total_job, "job")} h2.title
= render 'shared/search' | Find Your Next Job
/ , url_options: jobs_path p
| More then
/ latest job span
.latest-job.mb-5 = @total_job
.container.mb-5 | job listed here.
h2
| Latest jobs / search
hr.my-2 = render 'shared/search'
- @latest_jobs.each do |job|
.job-item.mb-4 / latest jobs
= link_to job.title, job, class: 'job-title' = render 'section_jobs', title: 'Latest Jobs',
.job-caption desc: "Here's the most recent job listed on the website.",
= link_to job.company.name, '#', class: 'job-company' jobs: @latest_jobs
p.job-salary
| Salary: / quotes
= job.salary .section.section-padding.bg-parallax[data-bg-image="assets/banner-5.jpg" data-overlay="50"]
.job-locations
- city_list = job.cities
= show_location(job.cities)
.job-desc
= truncate(simple_format(job.description), escape: false, length: 250)
hr.my-2
/ top cities
.top_cities.mb-5
.container .container
h2 Top cities .funfact-wrap.row
hr.my-2 .funfact.col-12
.row.align-items-start.mb-3 span.counter
- @top_cities.each do |city| | Something quotes
.col-4.city-item span.title
= link_to city[0], city_jobs_path(city_slug: city[1]), class: 'city-name' | Something quotes
span.job-count
| ( / suggest or topviews
= pluralize(city[2], 'job') - if user_signed_in? && current_user.industries?
|) = render 'section_jobs', title: 'Recommend for you',
= link_to 'See all cities', cities_path, class:'all-cities-btn' desc: 'Here are the hot jobs based on your favorite industries',
/ top industries jobs: @suggest_jobs
.top_industries.mb-5 - else
= render 'section_jobs', title: 'Attractive jobs',
desc: "Here's the most viewed jobs",
jobs: @attractive_jobs
/ count
.section.section-padding.bg-parallax[data-bg-image="assets/banner-2.jpg" data-overlay="50"]
.container
.funfact-wrap.row
.funfact.col-md-3.col-sm-6.col-12
span.counter
= @total_job
span.title
| Job Post
.funfact.col-md-3.col-sm-6.col-12
span.counter
= @member
span.title
| Members
.funfact.col-md-3.col-sm-6.col-12
span.counter
= @resume
span.title
| Resume
.funfact.col-md-3.col-sm-6.col-12
span.counter
= @company
span.title
| Company
/ industries
.section.section-padding
.container .container
h2 Top industries .section-title
hr.my-2 h2.title
.row.align-items-start | Industry
p
| Here's the most job listed by those industries.
.company-slider.row
- @top_industries.each do |industry| - @top_industries.each do |industry|
.col-4.industry-item .col
= link_to industry[0], industry_jobs_path(industry_slug: industry[1]), class: 'industry-name' = link_to industry_jobs_path(industry_slug: industry[1]) do
span.job-count = image_tag('logo-sample')
| ( h6.title
= pluralize(industry[2], 'job') = industry[0]
|) span.open-job
= link_to 'See all industries', industries_path, class:'all-industries-btn' | (
\ No newline at end of file = pluralize(industry[2], 'job')
|)
.text-center.mt-4.mt-lg-5
= link_to 'See all industries', industries_path, class:'btn btn-primary'
/ quotes
.section.section-padding.bg-parallax[data-bg-image="assets/banner-3.jpg" data-overlay="65"]
.container
.testimonial-slider.row
.col
.testimonial.text-center.text-white
p
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, modi sed praesentium necessitatibus tenetur neque, veritatis esse voluptatem
= image_tag('avt')
h6.name
| Ha Mai
span.title
| Marketer of VeNJob
.col
.testimonial.text-center.text-white
p
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, modi sed praesentium necessitatibus tenetur neque, veritatis esse voluptatem
= image_tag('avt')
h6.name
| Ha Mai
span.title
| CEO of VeNJob
.col
.testimonial.text-center.text-white
p
| Lorem, ipsum dolor sit amet consectetur adipisicing elit. Obcaecati, modi sed praesentium necessitatibus tenetur neque, veritatis esse voluptatem
= image_tag('avt')
h6.name
| Ha Mai
span.title
| Admin of VeNJob
/ cities
.section.section-padding
.container
.section-title
h2.title
| Cities
p
| Here's the most job listed by those industries.
.company-slider.row
- @top_cities.each do |city|
.col
= link_to city_jobs_path(city_slug: city[1]) do
= image_tag('logo-sample')
h6.title
= city[0]
span.open-job
| (
= pluralize(city[2], 'job')
|)
.text-center.mt-4.mt-lg-5
= link_to 'See all cities', cities_path, class:'btn btn-primary'
\ No newline at end of file
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "users/shared/error_messages", resource: resource %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>
<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>
<%= render "users/shared/links" %>
- provide(:title, 'Resend confirmation instructions')
= render 'shared/page_heading', title: 'Resend', url: new_user_confirmation_path
.section.section-padding
.container
.row.justify-content-center
.col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= render "users/shared/error_messages", resource: resource
.field
= f.label :email
br
= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email)
.actions
= f.submit "Resend confirmation instructions", class: 'btn btn-primary'
= render "users/shared/links"
- provide(:title, 'Forgot password') - provide(:title, 'Forgot password')
.container
.row.justify-content-center = render 'shared/page_heading', title: 'Forgot password', ulr: forgot_password_path
.col-6
h2.text-center.my-5 .section.section-padding
| Forgot password .container
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| .row.justify-content-center
= render 'users/shared/error_messages', resource: resource .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
.field.row.form-group.mb-4 = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
.col-2 = render 'users/shared/error_messages', resource: resource
= f.label :email, class: 'form-label' .field.row.form-group.mb-4
.col-10 .col-lg-2.col-sm-2.col-12
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' = f.label :email, class: 'form-label'
span.form-msg .col-lg-10.col-sm-10.col-12
- if devise_mapping.confirmable? && controller_name != 'confirmations' = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
p span.form-msg
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none' - if devise_mapping.confirmable? && controller_name != 'confirmations'
.actions.row.justify-content-end p
.col-10.d-flex.justify-content-center = link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
= f.submit 'Confirm your email', class: 'btn btn-primary w-75 my-4', data: { disable_with: false } .actions.row.justify-content-end
.col-lg-10.col-12.d-flex.justify-content-around
= f.submit 'Confirm your email', class: 'btn btn-primary w-100 my-4', data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
......
- provide(:title, 'Edit profile') - provide(:title, 'Edit profile')
.container = render 'shared/page_heading', title: "Edit #{resource_name.to_s.humanize}", url: login_path
.row.justify-content-center
.col-8
h2.text-center.my-5
| Edit
= resource_name.to_s.humanize
= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= render 'users/shared/error_messages', resource: resource
.field.row.mb-2.form-group
.col-3
= f.label :email, class: 'form-label'
.col-9
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
- if devise_mapping.confirmable? && resource.pending_reconfirmation?
div
| Currently waiting confirmation for:
= resource.unconfirmed_email
.field.row.mb-2.form-group
.col-3
= f.label :name, class: 'form-label'
.col-9
= f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-3
= f.label :address, class: 'form-label'
.col-9
= f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-3
= f.label :phone, class: 'form-label'
.col-9
= f.text_field :phone, autofocus: true, autocomplete: 'phone', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-3
= f.label :cv, class: 'form-label'
.col-9
= f.file_field :cv, accept: ApplyJob::ACCEPT_CONTENT_TYPE, class: 'form-control', direct_upload: true
.row.my-4.justify-content-end .section.section-padding
.col-9 .container
hr .row.justify-content-center
p .col-lg-8.col-sm-8.col-12.flex-grow-1.mb-4
|(leave password blank if you don't want to change it) = form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
= render 'users/shared/error_messages', resource: resource
.field.row.mb-2.form-group - if devise_mapping.confirmable? && resource.pending_reconfirmation?
.col-3 .text-info.text-center.mb-2
= f.label :password, class: 'form-label' | Currently waiting confirmation for:
.col-9 = resource.unconfirmed_email
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2' .field.row.mb-2.form-group
span.form-msg .col-lg-3.col-sm-3.col-12
.field.row.mb-2.form-group = f.label :email, class: 'form-label'
.col-3 .col-lg-9.col-sm-9.col-12
= f.label :password_confirmation, class: 'form-label' = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
.col-9 span.form-msg
= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2' .field.row.mb-2.form-group
span.form-msg .field.row.mb-2.form-group
.actions.row.justify-content-end .col-lg-3.col-sm-3.col-12
.col-9 = f.label :name, class: 'form-label'
= f.submit 'Done', class: 'btn btn-primary w-50 my-4', data: { disable_with: false } .col-lg-9.col-sm-9.col-12
hr = f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control mb-2'
h3 span.form-msg
| Delete my account .field.row.mb-2.form-group
p .col-lg-3.col-sm-3.col-12
| Click the button below to delete account = f.label :address, class: 'form-label'
= button_to 'Delete', registration_path(resource_name), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-primary w-100 my-4' .col-lg-9.col-sm-9.col-12
= link_to 'Home', :back = f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-lg-3.col-sm-3.col-12
= f.label :phone, class: 'form-label'
.col-lg-9.col-sm-9.col-12
= f.text_field :phone, autofocus: true, autocomplete: 'phone', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-lg-3.col-sm-3.col-12
= f.label :cv, class: 'form-label'
.col-lg-9.col-sm-9.col-12
= f.file_field :cv, accept: ApplyJob::ACCEPT_CONTENT_TYPE, direct_upload: true
span.form-msg
.row.my-4.justify-content-end
.col-lg-9.col-sm-9.col-12
hr
p
|(leave password blank if you don't want to change it)
.field.row.mb-2.form-group
.col-lg-3.col-sm-3.col-12
= f.label :password, class: 'form-label'
.col-lg-9.col-sm-9.col-12
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
span.form-msg
.field.row.mb-2.form-group
.col-lg-3.col-sm-3.col-12
= f.label :password_confirmation, class: 'form-label'
.col-lg-9.col-sm-9.col-12
= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2'
span.form-msg
.actions.row.justify-content-end
.col-lg-9.col-12
= f.submit 'Done', class: 'btn btn-primary w-100 my-4', data: { disable_with: false }
hr
.text-center
h3 Delete my account
p
| Click the button below to delete account
= button_to 'Delete', registration_path(resource_name), data: { confirm: 'Are you sure?' }, method: :delete, class: 'btn btn-primary w-100 my-4'
javascript: javascript:
Validator({ Validator({
...@@ -81,4 +79,4 @@ javascript: ...@@ -81,4 +79,4 @@ javascript:
Validator.isEmail('#user_email'), Validator.isEmail('#user_email'),
Validator.isRequired('#user_name') Validator.isRequired('#user_name')
] ]
}) })
\ No newline at end of file
- provide(:title, 'Sign Up') - provide(:title, 'Sign Up')
.container = render 'shared/page_heading', title: 'Sign up', url: signup_path
.row.justify-content-center
.col-6
h2.text-center.my-5 .section.section-padding
| Sign up .container
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| .row.justify-content-center
= render 'users/shared/error_messages', resource: resource .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
.field = form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= f.label :email, class: 'form-label' = render 'users/shared/error_messages', resource: resource
br .field.row.form-group.mb-4
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' .col-lg-2.col-sm-2.col-12
/ .field = f.label :email, class: 'form-label'
/ = f.label :name, class: 'form-label' .col-lg-10.col-sm-10.col-12
/ br = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
/ = f.text_field :name, autofocus: true, autocomplete: 'name', class: 'form-control mb-2' span.form-msg
/ .field .field
/ = f.label :address, class: 'form-label' = render 'users/shared/links'
/ br .actions.row.justify-content-end
/ = f.text_field :address, autofocus: true, autocomplete: 'address', class: 'form-control mb-2' .col-lg-10.col-12.d-flex.justify-content-around
/ .field = f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
/ = f.label :phone, class: 'form-label'
/ br javascript:
/ = f.text_field :phone, autofocus: true, autocomplete: 'phone', class: 'form-control mb-2' Validator({
/ .field form: '#new_user',
/ = f.label :password, class: 'form-label' errorSelector: '.form-msg',
/ - if @minimum_password_length rules: [
/ em Validator.isRequired('#user_email'),
/ | ( Validator.isEmail('#user_email')
/ = @minimum_password_length ]
/ | characters minimum) })
/ br
/ = f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
/ .field
/ = f.label :password_confirmation, class: 'form-label'
/ br
/ = f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2'
.actions
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
= render 'users/shared/links'
\ No newline at end of file
.container.text-center - provide(:title, 'Send email')
h2.my-5
| Register = render 'shared/page_heading', title: 'Check you email'
p
| Thank you for register our service, an confirmation email with registration link has been sent to your email. Please check your email within 24 hours. .section.section-padding
p .container.text-center
| Please note that the registration link is only valid for 24 hours. p
p | Thank you for register our service, an confirmation email with registration link has been sent to your email. Please check your email within 24 hours.
| Over that period, you will have to register your email again. p
\ No newline at end of file | Please note that the registration link is only valid for 24 hours.
p
| Over that period, you will have to register your email again.
\ No newline at end of file
- provide(:title, 'Log in') - provide(:title, 'Log in')
.container = render 'shared/page_heading', title: 'Login', url: login_path
.row.justify-content-center
.col-6 .section.section-padding
h2.text-center.my-5 .container
| Log in .row.justify-content-center
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| .col-lg-6.col-sm-6.col-12.flex-grow-1.mb-4
.field.row.form-group.mb-4 = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.col-2 .field.row.form-group.mb-4
= f.label :email, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :email, class: 'form-label'
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
.field.row.form-group.mb-4 span.form-msg
.col-2 .field.row.form-group.mb-4
= f.label :password, class: 'form-label' .col-lg-2.col-sm-2.col-12
.col-10 = f.label :password, class: 'form-label'
= f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2' .col-lg-10.col-sm-10.col-12
span.form-msg = f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2'
- if devise_mapping.rememberable? span.form-msg
.field - if devise_mapping.rememberable?
= f.check_box :remember_me .field
= f.label :remember_me, class: 'form-label mx-2' = f.check_box :remember_me
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' = f.label :remember_me, class: 'mx-2'
= link_to 'Forgot password?', forgot_password_path, class: 'text-decoration-none' .d-flex.justify-content-between
.actions.row.justify-content-end - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
.col-10.d-flex.justify-content-around = link_to 'Forgot password?', forgot_password_path, class: 'text-decoration-none'
= f.submit 'Log in', class: 'btn btn-primary w-25', data: { disable_with: false } = link_to 'Register now', new_registration_path(resource_name), class: 'mx-2'
= link_to 'Sign up', new_registration_path(resource_name), class: 'text-decoration-none w-25 btn btn-secondary' .actions.row.justify-content-end
.col-lg-10.col-12.d-flex.justify-content-around
= f.submit 'Log in', class: 'btn btn-primary w-100', data: { disable_with: false }
javascript: javascript:
Validator({ Validator({
......
- content_for :head do - content_for :head do
= stylesheet_link_tag 'users' = stylesheet_link_tag 'users'
.container = render 'shared/page_heading', title: 'User', url: user_profile_path
.main-body .section.py-5
/! Breadcrumb .container
nav.main-breadcrumb aria-label='breadcrumb' .main-body
ol.breadcrumb /! Breadcrumb
li.breadcrumb-item nav.main-breadcrumb aria-label='breadcrumb'
= link_to 'Home', root_path ol.breadcrumb
li.breadcrumb-item li.breadcrumb-item
= link_to 'User', '#' = link_to 'Home', root_path
li.breadcrumb-item.active aria-current='page' User Profile li.breadcrumb-item
/! /Breadcrumb = link_to 'User', '#'
.row.gutters-sm li.breadcrumb-item.active aria-current='page' User Profile
.col-md-4.mb-3 /! /Breadcrumb
.card .row.gutters-sm
.card-body .col-md-4.mb-3
.d-flex.flex-column.align-items-center.text-center .card
= gravatar_for @user .card-body
/ img.rounded-circle alt='Admin' src='https://bootdey.com/img/Content/avatar/avatar7.png' width='150' / .d-flex.flex-column.align-items-center.text-center
.mt-3 = gravatar_for @user
h4 / img.rounded-circle alt='Admin' src='https://bootdey.com/img/Content/avatar/avatar7.png' width='150' /
.mt-3
h4
= @user.name
p.text-secondary.mb-1 Full Stack Developer
p.text-muted.font-size-sm
= @user.address
button.btn.btn-primary Follow
button.btn.btn-outline-primary Message
.card.mt-3
ul.list-group.list-group-flush
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-globe.mr-2.icon-inline fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg'
circle cx='12' cy='12' r='10'
line x1='2' x2='22' y1='12' y2='12'
path d=('M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z')
| Website
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-github.mr-2.icon-inline fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg'
path d=('M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22')
| Github
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-twitter.mr-2.icon-inline.text-info fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg'
path d=('M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z')
| Twitter
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-instagram.mr-2.icon-inline.text-danger fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg'
rect height='20' rx='5' ry='5' width='20' x='2' y='2'
path d=('M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z')
line x1='17.5' x2='17.51' y1='6.5' y2='6.5'
| Instagram
span.text-secondary none
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap
h6.mb-0
svg.feather.feather-facebook.mr-2.icon-inline.text-primary fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg'
path d=('M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z')
| Facebook
span.text-secondary none
.col-md-8
.card.mb-3
.card-body
.row
.col-sm-3
h6.mb-0 Full Name
.col-sm-9.text-secondary
= @user.name = @user.name
p.text-secondary.mb-1 Full Stack Developer hr/
p.text-muted.font-size-sm .row
.col-sm-3
h6.mb-0 Email
.col-sm-9.text-secondary
= @user.email
hr/
.row
.col-sm-3
h6.mb-0 Phone
.col-sm-9.text-secondary
= @user.phone
hr/
.row
.col-sm-3
h6.mb-0 Address
.col-sm-9.text-secondary
= @user.address = @user.address
button.btn.btn-primary Follow hr/
button.btn.btn-outline-primary Message .row
.card.mt-3 .col-sm-3
ul.list-group.list-group-flush h6.mb-0 CV
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap .col-sm-9.text-secondary
h6.mb-0 - if @user.cv.attached?
svg.feather.feather-globe.mr-2.icon-inline fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg' = link_to @user.cv.filename, rails_blob_path(@user.cv, disposition: "attachment")
circle cx='12' cy='12' r='10' - else
line x1='2' x2='22' y1='12' y2='12' = 'cv file not uploaded yet'
path d=('M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z') hr/
| Website .row
span.text-secondary none .col-sm-12
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap = link_to 'Edit profile', edit_profile_path, class:'btn btn-info'
h6.mb-0 .row.gutters-sm
svg.feather.feather-github.mr-2.icon-inline fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg' .col-sm-6.mb-3
path d=('M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22') .card.h-100
| Github .card-body
span.text-secondary none h6.d-flex.align-items-center.mb-3
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap i.material-icons.text-info.mr-2> assignment
h6.mb-0 span.d-block.m-auto
svg.feather.feather-twitter.mr-2.icon-inline.text-info fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg' | Project Status
path d=('M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z') small Skill
| Twitter .progress.mb-3 style=('height: 5px')
span.text-secondary none .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='80' role='progressbar' style=('width: 80%')
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap small Skill
h6.mb-0 .progress.mb-3 style=('height: 5px')
svg.feather.feather-instagram.mr-2.icon-inline.text-danger fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg' .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='72' role='progressbar' style=('width: 72%')
rect height='20' rx='5' ry='5' width='20' x='2' y='2' small Skill
path d=('M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z') .progress.mb-3 style=('height: 5px')
line x1='17.5' x2='17.51' y1='6.5' y2='6.5' .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='89' role='progressbar' style=('width: 89%')
| Instagram small Skill
span.text-secondary none .progress.mb-3 style=('height: 5px')
li.list-group-item.d-flex.justify-content-between.align-items-center.flex-wrap .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='55' role='progressbar' style=('width: 55%')
h6.mb-0 small Skill
svg.feather.feather-facebook.mr-2.icon-inline.text-primary fill='none' height='24' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewbox=('0 0 24 24') width='24' xmlns='http://www.w3.org/2000/svg' .progress.mb-3 style=('height: 5px')
path d=('M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z') .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='66' role='progressbar' style=('width: 66%')
| Facebook .col-sm-6.mb-3
span.text-secondary none .card.h-100
.col-md-8 .card-body
.card.mb-3 h6.d-flex.align-items-center.mb-3
.card-body i.material-icons.text-info.mr-2> assignment
.row span.d-block.m-auto
.col-sm-3 | Project Status
h6.mb-0 Full Name small Skill
.col-sm-9.text-secondary .progress.mb-3 style=('height: 5px')
= @user.name .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='80' role='progressbar' style=('width: 80%')
hr/ small Skill
.row .progress.mb-3 style=('height: 5px')
.col-sm-3 .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='72' role='progressbar' style=('width: 72%')
h6.mb-0 Email small Skill
.col-sm-9.text-secondary .progress.mb-3 style=('height: 5px')
= @user.email .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='89' role='progressbar' style=('width: 89%')
hr/ small Skill
.row .progress.mb-3 style=('height: 5px')
.col-sm-3 .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='55' role='progressbar' style=('width: 55%')
h6.mb-0 Phone small Skill
.col-sm-9.text-secondary .progress.mb-3 style=('height: 5px')
= @user.phone .progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='66' role='progressbar' style=('width: 66%')
hr/
.row
.col-sm-3
h6.mb-0 Address
.col-sm-9.text-secondary
= @user.address
hr/
.row
.col-sm-3
h6.mb-0 CV
.col-sm-9.text-secondary
- if @user.cv.attached?
= link_to @user.cv.filename, rails_blob_path(@user.cv, disposition: "attachment")
- else
= 'cv file not uploaded yet'
hr/
.row
.col-sm-12
= link_to 'Edit profile', edit_profile_path, class:'btn btn-info'
.row.gutters-sm
.col-sm-6.mb-3
.card.h-100
.card-body
h6.d-flex.align-items-center.mb-3
i.material-icons.text-info.mr-2> assignment
span.d-block.m-auto
| Project Status
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='80' role='progressbar' style=('width: 80%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='72' role='progressbar' style=('width: 72%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='89' role='progressbar' style=('width: 89%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='55' role='progressbar' style=('width: 55%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='66' role='progressbar' style=('width: 66%')
.col-sm-6.mb-3
.card.h-100
.card-body
h6.d-flex.align-items-center.mb-3
i.material-icons.text-info.mr-2> assignment
span.d-block.m-auto
| Project Status
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='80' role='progressbar' style=('width: 80%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='72' role='progressbar' style=('width: 72%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='89' role='progressbar' style=('width: 89%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='55' role='progressbar' style=('width: 55%')
small Skill
.progress.mb-3 style=('height: 5px')
.progress-bar.bg-primary aria-valuemax='100' aria-valuemin='0' aria-valuenow='66' role='progressbar' style=('width: 66%')
...@@ -7,7 +7,8 @@ Rails.application.configure do ...@@ -7,7 +7,8 @@ Rails.application.configure do
# it changes. This slows down response time but is perfect for development # it changes. 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.
config.cache_classes = false config.cache_classes = false
# ngrok
config.hosts = nil
# Do not eager load code on boot. # Do not eager load code on boot.
config.eager_load = false config.eager_load = false
......
...@@ -24,10 +24,11 @@ Rails.application.routes.draw do ...@@ -24,10 +24,11 @@ Rails.application.routes.draw do
end end
root 'top#index' root 'top#index'
resources :cities, only: %i[index] resources :cities, only: %i[index]
resources :industries, only: %i[index] resources :industries, only: %i[index]
resources :favorite_jobs, only: %i[index create destroy] resources :favorite_jobs, only: %i[index create destroy]
resources :jobs, only: %i[index show] do resources :favorite_industries, only: %i[index create destroy]
resources :jobs, only: %i[index show] do
collection do collection do
get 'city/:city_slug', action: :index, as: :city get 'city/:city_slug', action: :index, as: :city
get 'industry/:industry_slug', action: :index, as: :industry get 'industry/:industry_slug', action: :index, as: :industry
......
class AddViewsCountToJobs < ActiveRecord::Migration[6.1]
def change
add_column :jobs, :views_count, :integer
end
end
class CreateFavoriteIndustries < ActiveRecord::Migration[6.1]
def change
create_table :favorite_industries do |t|
t.references :user, null: false, foreign_key: true
t.references :industry, null: false, foreign_key: true
t.timestamps
end
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: 2021_09_27_111928) do ActiveRecord::Schema.define(version: 2021_12_04_210000) do
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
...@@ -91,6 +91,15 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do ...@@ -91,6 +91,15 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
end end
create_table "favorite_industries", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "user_id", null: false
t.bigint "industry_id", null: false
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["industry_id"], name: "index_favorite_industries_on_industry_id"
t.index ["user_id"], name: "index_favorite_industries_on_user_id"
end
create_table "favorite_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "favorite_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "job_id", null: false t.bigint "job_id", null: false
t.bigint "user_id", null: false t.bigint "user_id", null: false
...@@ -143,6 +152,7 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do ...@@ -143,6 +152,7 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.integer "min_salary" t.integer "min_salary"
t.integer "max_salary" t.integer "max_salary"
t.integer "views_count"
t.index ["company_id"], name: "index_jobs_on_company_id" t.index ["company_id"], name: "index_jobs_on_company_id"
end end
...@@ -183,6 +193,8 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do ...@@ -183,6 +193,8 @@ ActiveRecord::Schema.define(version: 2021_09_27_111928) do
add_foreign_key "apply_jobs", "users" add_foreign_key "apply_jobs", "users"
add_foreign_key "cities_jobs", "cities" add_foreign_key "cities_jobs", "cities"
add_foreign_key "cities_jobs", "jobs" add_foreign_key "cities_jobs", "jobs"
add_foreign_key "favorite_industries", "industries"
add_foreign_key "favorite_industries", "users"
add_foreign_key "favorite_jobs", "jobs" add_foreign_key "favorite_jobs", "jobs"
add_foreign_key "favorite_jobs", "users" add_foreign_key "favorite_jobs", "users"
add_foreign_key "history_jobs", "jobs" add_foreign_key "history_jobs", "jobs"
......
# This file should contain all the record creation needed to seed the database with its default values. # reset views count of jobs
# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
# Job.find_in_batches do |jobs|
# Examples: jobs.each do |job|
# job.update_attribute :views_count, 0
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) end
# Character.create(name: 'Luke', movie: movies.first) end
require 'rsolr' require 'rsolr'
namespace :solr do namespace :solr do
# rails solr:[task]
desc 'solr index data' desc 'solr index data'
task add_data: :environment do task add_data: :environment do
logger.info "start at #{Time.current}" logger.info "start at #{Time.current}"
......
...@@ -116,6 +116,7 @@ namespace :crawler do ...@@ -116,6 +116,7 @@ namespace :crawler do
benefit: benefits, benefit: benefits,
requirement: requirement, requirement: requirement,
other_info: other_info, other_info: other_info,
views_count: 0,
company_id: company_object.id }) company_id: company_object.id })
industry_objects = industries.map { |industry| Industry.find_or_create_by(name: industry, slug: industry.to_slug) } industry_objects = industries.map { |industry| Industry.find_or_create_by(name: industry, slug: industry.to_slug) }
job_object.industries << industry_objects job_object.industries << industry_objects
...@@ -123,6 +124,7 @@ namespace :crawler do ...@@ -123,6 +124,7 @@ namespace :crawler do
cities = job_page.css('.job-detail-content .detail-box .map p a').map(&:text) cities = job_page.css('.job-detail-content .detail-box .map p a').map(&:text)
city_objects = cities.map { |city| City.find_or_create_by(name: city, slug: city.to_slug) } city_objects = cities.map { |city| City.find_or_create_by(name: city, slug: city.to_slug) }
job_object.cities << city_objects job_object.cities << city_objects
rescue URI::InvalidURIError => e rescue URI::InvalidURIError => e
puts "[Error] #{e.message}" puts "[Error] #{e.message}"
logger.error "URI must be ascii only : #{url}" logger.error "URI must be ascii only : #{url}"
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
"name": "ven-job", "name": "ven-job",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@babel/plugin-proposal-private-methods": "^7.16.0",
"@popperjs/core": "^2.9.2", "@popperjs/core": "^2.9.2",
"@rails/actioncable": "^6.0.0", "@rails/actioncable": "^6.0.0",
"@rails/activestorage": "^6.0.0", "@rails/activestorage": "^6.0.0",
"@rails/ujs": "^6.0.0", "@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.4.0", "@rails/webpacker": "5.4.0",
"bootstrap": "^5.0.0-beta3",
"bs-stepper": "^1.7.0", "bs-stepper": "^1.7.0",
"jquery": "^3.6.0", "jquery": "^3.6.0",
"turbolinks": "^5.2.0", "turbolinks": "^5.2.0",
......
require "test_helper"
class FavoriteIndustriesControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
user: one
industry: one
two:
user: two
industry: two
require "test_helper"
class FavoriteIndustryTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
...@@ -9,6 +9,13 @@ ...@@ -9,6 +9,13 @@
dependencies: dependencies:
"@babel/highlight" "^7.14.5" "@babel/highlight" "^7.14.5"
"@babel/code-frame@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
dependencies:
"@babel/highlight" "^7.16.0"
"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7": "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7":
version "7.14.7" version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
...@@ -44,6 +51,15 @@ ...@@ -44,6 +51,15 @@
jsesc "^2.5.1" jsesc "^2.5.1"
source-map "^0.5.0" source-map "^0.5.0"
"@babel/generator@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
dependencies:
"@babel/types" "^7.16.0"
jsesc "^2.5.1"
source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.14.5": "@babel/helper-annotate-as-pure@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61"
...@@ -51,6 +67,13 @@ ...@@ -51,6 +67,13 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-annotate-as-pure@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d"
integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": "@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191"
...@@ -81,6 +104,18 @@ ...@@ -81,6 +104,18 @@
"@babel/helper-replace-supers" "^7.14.5" "@babel/helper-replace-supers" "^7.14.5"
"@babel/helper-split-export-declaration" "^7.14.5" "@babel/helper-split-export-declaration" "^7.14.5"
"@babel/helper-create-class-features-plugin@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b"
integrity sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.16.0"
"@babel/helper-function-name" "^7.16.0"
"@babel/helper-member-expression-to-functions" "^7.16.0"
"@babel/helper-optimise-call-expression" "^7.16.0"
"@babel/helper-replace-supers" "^7.16.0"
"@babel/helper-split-export-declaration" "^7.16.0"
"@babel/helper-create-regexp-features-plugin@^7.14.5": "@babel/helper-create-regexp-features-plugin@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4"
...@@ -119,6 +154,15 @@ ...@@ -119,6 +154,15 @@
"@babel/template" "^7.14.5" "@babel/template" "^7.14.5"
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-function-name@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
dependencies:
"@babel/helper-get-function-arity" "^7.16.0"
"@babel/template" "^7.16.0"
"@babel/types" "^7.16.0"
"@babel/helper-get-function-arity@^7.14.5": "@babel/helper-get-function-arity@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815"
...@@ -126,6 +170,13 @@ ...@@ -126,6 +170,13 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-get-function-arity@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-hoist-variables@^7.14.5": "@babel/helper-hoist-variables@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d"
...@@ -133,6 +184,13 @@ ...@@ -133,6 +184,13 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-hoist-variables@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-member-expression-to-functions@^7.14.5": "@babel/helper-member-expression-to-functions@^7.14.5":
version "7.14.7" version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970"
...@@ -140,6 +198,13 @@ ...@@ -140,6 +198,13 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-member-expression-to-functions@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3"
...@@ -168,6 +233,13 @@ ...@@ -168,6 +233,13 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-optimise-call-expression@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
...@@ -192,6 +264,16 @@ ...@@ -192,6 +264,16 @@
"@babel/traverse" "^7.14.5" "@babel/traverse" "^7.14.5"
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-replace-supers@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.16.0"
"@babel/helper-optimise-call-expression" "^7.16.0"
"@babel/traverse" "^7.16.0"
"@babel/types" "^7.16.0"
"@babel/helper-simple-access@^7.14.5": "@babel/helper-simple-access@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4"
...@@ -213,11 +295,23 @@ ...@@ -213,11 +295,23 @@
dependencies: dependencies:
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/helper-split-export-declaration@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
dependencies:
"@babel/types" "^7.16.0"
"@babel/helper-validator-identifier@^7.14.5": "@babel/helper-validator-identifier@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8"
integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==
"@babel/helper-validator-identifier@^7.15.7":
version "7.15.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
"@babel/helper-validator-option@^7.14.5": "@babel/helper-validator-option@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
...@@ -251,11 +345,25 @@ ...@@ -251,11 +345,25 @@
chalk "^2.0.0" chalk "^2.0.0"
js-tokens "^4.0.0" js-tokens "^4.0.0"
"@babel/highlight@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
dependencies:
"@babel/helper-validator-identifier" "^7.15.7"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7": "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7":
version "7.14.7" version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
"@babel/parser@^7.16.0", "@babel/parser@^7.16.3":
version "7.16.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e"
integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng==
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e"
...@@ -375,6 +483,14 @@ ...@@ -375,6 +483,14 @@
"@babel/helper-create-class-features-plugin" "^7.14.5" "@babel/helper-create-class-features-plugin" "^7.14.5"
"@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-proposal-private-methods@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6"
integrity sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.16.0"
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-proposal-private-property-in-object@^7.14.5": "@babel/plugin-proposal-private-property-in-object@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.5.tgz#9f65a4d0493a940b4c01f8aa9d3f1894a587f636"
...@@ -857,6 +973,15 @@ ...@@ -857,6 +973,15 @@
"@babel/parser" "^7.14.5" "@babel/parser" "^7.14.5"
"@babel/types" "^7.14.5" "@babel/types" "^7.14.5"
"@babel/template@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
dependencies:
"@babel/code-frame" "^7.16.0"
"@babel/parser" "^7.16.0"
"@babel/types" "^7.16.0"
"@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5": "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5":
version "7.14.7" version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753"
...@@ -872,6 +997,21 @@ ...@@ -872,6 +997,21 @@
debug "^4.1.0" debug "^4.1.0"
globals "^11.1.0" globals "^11.1.0"
"@babel/traverse@^7.16.0":
version "7.16.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787"
integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==
dependencies:
"@babel/code-frame" "^7.16.0"
"@babel/generator" "^7.16.0"
"@babel/helper-function-name" "^7.16.0"
"@babel/helper-hoist-variables" "^7.16.0"
"@babel/helper-split-export-declaration" "^7.16.0"
"@babel/parser" "^7.16.3"
"@babel/types" "^7.16.0"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.14.5", "@babel/types@^7.4.4": "@babel/types@^7.14.5", "@babel/types@^7.4.4":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff"
...@@ -880,6 +1020,14 @@ ...@@ -880,6 +1020,14 @@
"@babel/helper-validator-identifier" "^7.14.5" "@babel/helper-validator-identifier" "^7.14.5"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@babel/types@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba"
integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==
dependencies:
"@babel/helper-validator-identifier" "^7.15.7"
to-fast-properties "^2.0.0"
"@csstools/convert-colors@^1.4.0": "@csstools/convert-colors@^1.4.0":
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7"
...@@ -1496,11 +1644,6 @@ boolbase@^1.0.0, boolbase@~1.0.0: ...@@ -1496,11 +1644,6 @@ boolbase@^1.0.0, boolbase@~1.0.0:
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
bootstrap@^5.0.0-beta3:
version "5.0.0-beta3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.0.0-beta3.tgz#c959f61fbd03667a1b158f763856994859d7a465"
integrity sha512-0urccjfIOzhrb9qJysN8XW/DRw6rg3zH7qLeKIp4Zyl8+Ens4JWB0NC0cB5AhnSFPd2tftRggjwCMxablo6Tpg==
brace-expansion@^1.1.7: brace-expansion@^1.1.7:
version "1.1.11" version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
...@@ -1760,9 +1903,9 @@ caniuse-api@^3.0.0: ...@@ -1760,9 +1903,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0" lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219: caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219:
version "1.0.30001240" version "1.0.30001286"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001240.tgz#ec15d125b590602c8731545c5351ff054ad2d52f" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001286.tgz"
integrity sha512-nb8mDzfMdxBDN7ZKx8chWafAdBp5DAAlpWvNyUGe5tcDWd838zpzDN3Rah9cjCqhfOKkrvx40G2SDtP0qiWX/w== integrity sha512-zaEMRH6xg8ESMi2eQ3R4eZ5qw/hJiVsO/HlLwniIwErij0JDr9P+8V4dtx1l+kLq6j3yy8l8W4fst1lBnat5wQ==
case-sensitive-paths-webpack-plugin@^2.4.0: case-sensitive-paths-webpack-plugin@^2.4.0:
version "2.4.0" version "2.4.0"
......
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