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'
gem 'httparty', '~> 0.18.1'
gem 'active_storage_validations', '~> 0.9.5'
gem 'devise', '~> 4.8'
gem 'jquery-rails', '~> 4.4'
gem 'rsolr', '~> 2.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
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
ast (2.4.2)
autoprefixer-rails (10.3.3.0)
execjs (~> 2)
bcrypt (3.1.16)
bindex (0.8.1)
bootsnap (1.9.1)
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)
bullet (6.1.5)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.1.3)
capybara (3.35.3)
capybara (3.36.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (3.0.0)
childprocess (4.1.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
crass (1.0.6)
......@@ -110,6 +117,7 @@ GEM
responders
warden (~> 1.2.3)
erubi (1.10.0)
execjs (2.8.1)
faraday (1.8.0)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
......@@ -130,12 +138,14 @@ GEM
faraday-patron (1.0.0)
faraday-rack (1.0.0)
ffi (1.15.4)
font-awesome-rails (4.7.0.7)
railties (>= 3.2, < 7)
globalid (0.5.2)
activesupport (>= 5.0)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.8.10)
i18n (1.8.11)
concurrent-ruby (~> 1.0)
jbuilder (2.11.2)
activesupport (>= 5.0.0)
......@@ -152,11 +162,12 @@ GEM
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2021.0901)
mini_mime (1.1.1)
mini_mime (1.1.2)
minitest (5.14.4)
msgpack (1.4.2)
multi_xml (0.6.0)
......@@ -169,15 +180,16 @@ GEM
parallel (1.21.0)
parser (3.0.2.0)
ast (~> 2.4.1)
popper_js (1.16.0)
pry (0.14.1)
coderay (~> 1.1)
method_source (~> 1.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.6)
puma (5.5.0)
puma (5.5.2)
nio4r (~> 2.0)
racc (1.5.2)
racc (1.6.0)
rack (2.2.3)
rack-mini-profiler (2.3.3)
rack (>= 1.2.0)
......@@ -226,7 +238,7 @@ GEM
faraday (>= 0.9.0)
rsolr-ext (1.0.3)
rsolr (>= 1.0.2)
rubocop (1.22.0)
rubocop (1.22.3)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
......@@ -235,9 +247,9 @@ GEM
rubocop-ast (>= 1.12.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.12.0)
rubocop-ast (1.13.0)
parser (>= 3.0.1.1)
rubocop-rails (2.12.2)
rubocop-rails (2.12.4)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.7.0, < 2.0)
......@@ -254,8 +266,9 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
selenium-webdriver (4.0.3)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2)
semantic_range (3.0.0)
slim (4.1.0)
......@@ -290,10 +303,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webdrivers (4.6.1)
webdrivers (5.0.0)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (>= 3.0, < 4.0)
selenium-webdriver (~> 4.0)
webpacker (5.4.3)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
......@@ -304,7 +317,7 @@ GEM
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.4.2)
zeitwerk (2.5.1)
PLATFORMS
x86_64-linux
......@@ -312,10 +325,12 @@ PLATFORMS
DEPENDENCIES
active_storage_validations (~> 0.9.5)
bootsnap (>= 1.4.4)
bootstrap (~> 4.4.1)
bullet (~> 6.1, >= 6.1.4)
byebug
capybara (>= 3.26)
devise (~> 4.8)
font-awesome-rails (~> 4.7, >= 4.7.0.7)
httparty (~> 0.18.1)
jbuilder (~> 2.7)
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
/* 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
/* 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
# before_action :logged_in_user
before_action :authenticate_user!
before_action :load_job, only: %i[create destroy]
......
class JobsController < ApplicationController
before_action :history, only: :show
before_action :views_count, only: :show
before_action :salary_search
before_action :city_industry_list
before_action :name, only: :index
......@@ -31,6 +32,13 @@ class JobsController < ApplicationController
history.update(updated_at: Time.current)
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
@name = if params[:city_slug]
City.find_by(slug: params[:city_slug]).name
......@@ -44,6 +52,6 @@ class JobsController < ApplicationController
def get_jobs(query)
jobs_ids = query['response']['docs'].map { |j| j['job_id'] }
@jobs = Job.eager_load(:cities, :cities_jobs, :company).find(jobs_ids)
@jobs_count = query['numFound']
@jobs_count = query['response']['numFound']
end
end
class TopController < ApplicationController
before_action :salary_search
before_action :city_industry_list
before_action :solr
def index
solr = Solr.new(params)
@latest_jobs = get_jobs(solr.latest_jobs)
@total_job = solr.query_all['response']['numFound']
@total_job = 100
@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)
@latest_jobs = get_jobs(@solr.latest_jobs)
@attractive_jobs = Job.top_views
@total_job = @solr.query_all['response']['numFound']
@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)
@member = User.count
@resume = ApplyJob.count
@company = Company.count
suggest
end
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)
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
......@@ -16,12 +16,12 @@ module ApplicationHelper
a = list.map do |item|
case model
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
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
a.join('|').html_safe
a.join(' | ').html_safe
end
def view_search_result
......
module FavoriteIndustriesHelper
end
......@@ -4,7 +4,9 @@
// that code so it'll be compiled.
//= require jquery
//= require jquery_ujs
//= require jquery_ujs
//= require popper
//= require bootstrap
//= require turbolinks
//= require_tree .
......@@ -17,7 +19,5 @@ Rails.start()
Turbolinks.start()
ActiveStorage.start()
import "bootstrap"
window.bootstrap = require("bootstrap");
import "../stylesheets/application.scss";
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
TOP_JOB_COUNT = 9
has_and_belongs_to_many :jobs
has_many :favorite_industries, dependent: :destroy
validates :slug, presence: true, uniqueness: { case_sensitive: true }
......
......@@ -14,4 +14,8 @@ class Job < ApplicationRecord
has_many :apply_jobs, dependent: :destroy
has_many :favorite_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
......@@ -7,6 +7,7 @@ class User < ApplicationRecord
has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs, dependent: :destroy
has_many :favorite_industries, dependent: :destroy
has_one_attached :cv
......@@ -32,6 +33,20 @@ class User < ApplicationRecord
@favorite_job_ids.include?(job.id)
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
def password_required?
......
......@@ -62,7 +62,7 @@ class Solr
city_name = city.name
q = "search:*#{@params[:search]}*"
fq = if @params[:salary]
fq = if @params[:salary].present?
["cities_name: \"#{escape_str(city_name)}\"", "min_salary: [#{@params[:salary]} TO *]"]
else
"cities_name: \"#{escape_str(city_name)}\""
......@@ -78,7 +78,7 @@ class Solr
industry_name = industry.name
q = "search:*#{@params[:search]}*"
fq = if @params[:salary]
fq = if @params[:salary].present?
["industries_name: \"#{escape_str(industry_name)}\"", "min_salary: [#{@params[:salary]} TO *]"]
else
"industries_name: \"#{escape_str(industry_name)}\""
......@@ -87,6 +87,16 @@ class Solr
send_request(q, fq)
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)
q = '*:*'
fq = '*:*'
......
......@@ -2,88 +2,87 @@
- provide(:title, 'All applies jobs')
/ search
.container.mt-5
= form_with(url: admin_applies_jobs_path, method: :get, local: true) do |f|
.row.mb-2.form-group
.col-2
= f.label :email, 'Email', class: 'form-label'
.col-10
= f.text_field :email, class: 'form-control', value: params[:email]
.row.mb-2.form-group
.col-2
= f.label :city, 'City'
.col-10
= f.select :city, options_for_select(@city, selected: params[:city]), { include_blank: 'Select city' }, { class: 'form-select' }
.row.mb-2.form-group
.col-2
= 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' }
= render 'shared/page_heading', title: 'Applies jobs', url: history_jobs_path
.section.section-padding
.container
= form_with(url: admin_applies_jobs_path, method: :get, local: true) do |f|
.row.mb-2.form-group
.col-2
= f.label :email, 'Email', class: 'form-label'
.col-10
= f.text_field :email, class: 'form-control', value: params[:email]
.row.mb-2.form-group
.col-2
= f.label :city, 'City'
.col-10
= f.select :city, options_for_select(@city, selected: params[:city]), { include_blank: 'Select city' }, { class: 'form-select' }
.row.mb-2.form-group
.col-2
= 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
.col-6
.row
.col-4
= f.label :date_start, 'From', class: 'form-label'
.col-8
= f.date_field :date_start, value: params[:date_start], class: 'form-control'
.col-6
.row
.col-4
= f.label :date_end, 'To', class: 'form-label'
.col-8
= f.date_field :date_end, value: params[:date_end], class: 'form-control'
.row
.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 }
.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 }
.row.mb-2.form-group
.col-6
.row
.col-4
= f.label :date_start, 'From', class: 'form-label'
.col-8
= f.date_field :date_start, value: params[:date_start], class: 'form-control'
.col-6
.row
.col-4
= f.label :date_end, 'To', class: 'form-label'
.col-8
= f.date_field :date_end, value: params[:date_end], class: 'form-control'
.row
.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 }
.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 }
/result
.container
h2.my-5.text-center
| All applies jobs
.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
.container
- @apply_jobs.each do |apply|
.apply-item
.apply-job-title
= link_to apply.job.title, apply.job, class: 'job-title fs-3 text-decoration-none text-reset'
.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
/result
.container.mb-3
.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
.container
- @apply_jobs.each do |apply|
.apply-item
.apply-job-title
= link_to apply.job.title, apply.job, class: 'job-title fs-3 text-decoration-none text-reset'
.apply-user-name.text-secondary
p.fw-bold
| Candidate Name:
span.fw-normal.text-dark
= 'cv file not uploaded yet'
.d-flex.align-items-center.justify-content-between
.apply-user-email
= apply.user_name
.apply-cv
p.fw-bold.text-secondary
| Candidate's Email:
span.fw-normal.text-dark
= apply.email
.apply-date
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
| 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
= 'cv file not uploaded yet'
.d-flex.align-items-center.justify-content-between
.apply-user-email
p.fw-bold.text-secondary
| Candidate's Email:
span.fw-normal.text-dark
= apply.email
.apply-date
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')
= render 'shared/page_heading', title: 'Forgot password', url: login_path
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Forgot password
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f|
= render 'admins/shared/error_messages', resource: resource
.field.row.form-group.mb-4
.col-2
= f.label :email, class: 'form-label'
.col-10
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
- if devise_mapping.confirmable? && controller_name != 'confirmations'
p
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
.actions.row.justify-content-end
.col-10.d-flex.justify-content-center
= f.submit 'Confirm your email', class: 'btn btn-primary w-75 my-4', data: { disable_with: false }
.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: password_path(resource_name), html: { method: :post }) do |f|
= render 'admins/shared/error_messages', resource: resource
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :email, class: 'form-label'
.col-lg-10.col-sm-10.col-12
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
- if devise_mapping.confirmable? && controller_name != 'confirmations'
p
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name), class: 'text-decoration-none'
.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:
Validator({
......
- provide(:title, 'Admin Sign Up')
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Sign up
= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= render 'users/shared/error_messages', resource: resource
.field.row.form-group.mb-4
.col-2
= f.label :email, class: 'form-label'
.col-10
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-2
= f.label :password, class: 'form-label'
.col-10
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-2
= f.label :password_confirmation, class: 'form-label'
.col-10
= f.password_field :password_confirmation, autocomplete: 'new-password', class: 'form-control mb-2'
span.form-msg
.actions
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
= render 'shared/page_heading', title: 'Sign up', url: new_admin_registration_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: registration_path(resource_name)) do |f|
= render 'users/shared/error_messages', resource: resource
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :email, class: 'form-label'
.col-lg-10.col-sm-10.col-12
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :password, class: 'form-label'
.col-lg-10.col-sm-10.col-12
= f.password_field :password, autocomplete: 'new-password', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :password_confirmation, class: 'form-label'
.col-lg-10.col-sm-10.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-10.col-12.d-flex.justify-content-around
= f.submit 'Sign up', class: 'btn btn-primary w-100 my-5'
javascript:
Validator({
......
- provide(:title, 'Log in')
.container
.row.justify-content-center
.col-6
h2.text-center.my-5
| Log in Admin
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
.field.row.form-group.mb-4
.col-2
= f.label :email, class: 'form-label'
.col-10
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-2
= f.label :password, class: 'form-label'
.col-10
= f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2'
span.form-msg
- if devise_mapping.rememberable?
.field
= f.check_box :remember_me
= f.label :remember_me, class: 'form-label mx-2'
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
= link_to 'Forgot password?', forgot_password_path, class: 'text-decoration-none'
.actions.row.justify-content-end
.col-10.d-flex.justify-content-around
= 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 w-25 btn btn-secondary'
= render 'shared/page_heading', title: 'Admin Login', url: admin_login_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: session_path(resource_name)) do |f|
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :email, class: 'form-label'
.col-lg-10.col-sm-10.col-12
= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'form-control mb-2'
span.form-msg
.field.row.form-group.mb-4
.col-lg-2.col-sm-2.col-12
= f.label :password, class: 'form-label'
.col-lg-10.col-sm-10.col-12
= f.password_field :password, autocomplete: 'current-password', class: 'form-control mb-2'
span.form-msg
- if devise_mapping.rememberable?
.field
= f.check_box :remember_me
= f.label :remember_me, class: 'form-label mx-2'
.d-flex.justify-content-between
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
= link_to 'Forgot password?', new_admin_password_path, class: 'text-decoration-none'
= link_to 'Sign up', new_registration_path(resource_name), class: 'text-decoration-none'
.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:
Validator({
......
.job-item
.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'
- if user_signed_in? && current_user.favorite?(applied_job.job)
= render 'shared/unfavorite', job_id: applied_job.job.id
- else
= render 'shared/favorite', job_id: applied_job.job.id
.job-caption
= link_to applied_job.job.company.name, '#', class: 'job-company text-decoration-none text-secondary'
p.job-salary.text-success
| Salary: #{applied_job.job.salary}
ul.list-unstyled
= show_location(applied_job.job.cities)
.job-desc
= truncate(simple_format(applied_job.job.description), escape: false, length: 250)
.applied-at
/ .job-item
/ .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'
/ - if user_signed_in? && current_user.favorite?(applied_job.job)
/ = render 'shared/unfavorite', job_id: applied_job.job.id
/ - else
/ = render 'shared/favorite', job_id: applied_job.job.id
/ .job-caption
/ = link_to applied_job.job.company.name, '#', class: 'job-company text-decoration-none text-secondary'
/ p.job-salary.text-success
/ | Salary: #{applied_job.job.salary}
/ ul.list-unstyled
/ = show_location(applied_job.job.cities)
/ .job-desc
/ = truncate(simple_format(applied_job.job.description), escape: false, length: 250)
/ .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:
= applied_job.updated_at.strftime('%d/%m/%Y')
hr.my-4
- provide(:title, 'Confirmation')
.container
= render 'ribbon'
= render 'shared/page_heading', title: 'Confirm', url: '#'
.container
h1.my-5.text-center
| Confirmation
.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
.section
.container
= render 'ribbon'
.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.form-control
= 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'
.container
.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
= 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')
.container
=render 'ribbon'
= render 'shared/page_heading', title: 'Done', url: '#'
.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
.section.py-5
.container
=render 'ribbon'
.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')
.container.py-5
h1.text-center.my-job-label My Job
.no-padding.d-flex.align-items-center.flex-column
.page-info.p-2
= page_entries_info @jobs
.page-info.p-2
= paginate @jobs
= render partial: "my_jobs", collection: @jobs, as: :applied_job
.no-padding.d-flex.align-items-center.flex-column
.page-info.p-2
= page_entries_info @jobs
.page-info.p-2
= paginate @jobs
= render 'shared/page_heading', title: 'APPlIED JOBS', url: apply_jobs_path
.section.section-padding
.container
.job-list-toolbar
.page-info.p-2
= page_entries_info @jobs
.job-list-wrap
= render partial: "my_jobs", collection: @jobs, as: :applied_job
ul.pagination.pagination-center.mt-5
= paginate @jobs
\ No newline at end of file
- provide(:title, 'Apply job')
.container
= render 'ribbon'
.container
h1.my-5.text-center
| Apply Form
p.fs-5.fw-bold.mb-4.text-center
= @job.title
.col
= form_with(model: @apply, url: confirm_job_path, local: true, id: 'apply-form') do |f|
= render 'shared/error_messages', object: f.object
.row.mb-5.form-group
= f.hidden_field :job_id, value: @job.id
.col-2
= f.label :user_name, 'Full name', class: 'form-label label'
.col-10
= f.text_field :user_name, value: @apply.user_name || @current_user.name, class: 'form-control'
span.form-msg
.row.mb-5.form-group
.col-2
= f.label :email, class: 'form-label label'
.col-10
= f.text_field :email, value: @apply.email || @current_user.email, class: 'form-control'
span.form-msg
.row.mb-5.form-group
/ - if @user.cv.attached?
/ = url_for(@user.cv)
.col-2
= f.label :cv, class: 'form-label label'
.col-10
= f.file_field :cv, files: @blob, accept: ApplyJob::ACCEPT_CONTENT_TYPE, class: 'form-control'
span.form-msg
br
= f.submit 'Confirm', class: 'btn btn-primary w-25 my-4 btn-height',data: { disable_with: false }
= render 'shared/page_heading', title: 'Apply form', url: '#'
.section
.container.py-5
= render 'ribbon'
.container
h3.fs-5.fw-bold.mb-4.text-center
= @job.title
.col
= form_with(model: @apply, url: confirm_job_path, local: true, id: 'apply-form') do |f|
= render 'shared/error_messages', object: f.object
.row.mb-5.form-group
= f.hidden_field :job_id, value: @job.id
.col-2
= f.label :user_name, 'Full name', class: 'form-label label'
.col-10
= f.text_field :user_name, value: @apply.user_name || @current_user.name, class: 'form-control'
span.form-msg
.row.mb-5.form-group
.col-2
= f.label :email, class: 'form-label label'
.col-10
= f.text_field :email, value: @apply.email || @current_user.email, class: 'form-control'
span.form-msg
.row.mb-5.form-group
/ - if @user.cv.attached?
/ = url_for(@user.cv)
.col-2
= f.label :cv, class: 'form-label label'
.col-10
= f.file_field :cv, files: @blob, accept: ApplyJob::ACCEPT_CONTENT_TYPE
span.form-msg
br
= f.submit 'Confirm', class: 'btn btn-primary w-25 my-4 btn-height',data: { disable_with: false }
javascript:
Validator({
......
- provide(:title, 'Cities')
= render 'shared/page_heading', title: 'Cities', url: cities_path
/region
.countries-list
.container.py-5
h2.mt-0 REGION
hr.my-4
.row
- @regions.each do |region|
.col-lg-4.col-md-6.text-center
.mt-5
h3.h4.mb-2.text-white.see-more-text= link_to region.upcase, anchor: region
// cities list
.cities-list
.container
- @job_quantity_by_region.each do |region, city_job_count|
.countries-job-list id=region
.container-fullwidth.py-5
h2.mt-0
= region.upcase
hr.my-4
.row
- city_job_count.each do |city|
.col-lg-4.col-md-6.text-center
.mt-5
.city-item
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
.section.section-padding
.container
.countries-list
.container.py-5
h2.mt-0 REGION
hr.my-4
.row
- @regions.each do |region|
.col-lg-4.col-md-6.text-center
.mt-5
h3.mb-2.text-primary.see-more-text= link_to region.upcase, anchor: region
// cities list
.cities-list
.container
- @job_quantity_by_region.each do |region, city_job_count|
.countries-job-list id=region
.container-fullwidth.py-5
h2.mt-0
= region.upcase
hr.my-4
.row
- city_job_count.each do |city|
.col-lg-4.col-md-6.col-12.text-center
.mt-5
.city-item
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')
= render 'shared/page_heading', title: 'FAVORITE', url: favorite_jobs_path
- 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
= render partial: 'shared/jobs_list_index', object: @favorite_jobs, as: 'jobs'
- provide(:title, 'History page')
= render 'shared/page_heading', title: 'HISTORY', url: history_jobs_path
- if @history_jobs.empty?
h2 No jobs in your history
.section.section-padding
.container.text-center
h2 No jobs in your history
- else
= render partial: 'shared/jobs_list_index', object: @history_jobs, as: 'jobs'
.countries-list
.container.py-5
h2.mt-0 INDUSTRIES
hr.my-4
- provide(:title, 'Industries')
= render 'shared/page_heading', title: 'INDUSTRIES', url: industries_path
.section.section-padding
.container
#info-box.row
- @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
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')
.row
.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
/ 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')
/ 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'
.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
.container
.section.section-padding
.container
- @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
h3
= view_search_result
.job-list-toolbar
.page-info.p-2
= page_entries_info @jobs
.job-list-wrap
- @jobs.each do |job|
= link_to job, class: 'job-list' do
.company-logo.col-auto
= image_tag('company-logo', width: '120')
.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)
/ 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:
city_list = @job.cities
industry_list = @job.industries
/ 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
.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
= @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
ol.breadcrumb
li.breadcrumb-item
= link_to 'Home', root_path
li.breadcrumb-item
= show_breadcrumb(city_list, :city)
li.breadcrumb-item
= show_breadcrumb(industry_list, :industry)
li.breadcrumb-item.active
= @job.title
.section.section-padding
.container
.row.mb-n5
.col-lg-8.col-12.mb-5.pr-lg-5
.job-list-details
.job-details-head.row.mx-0
.company-logo.col-auto
= image_tag('company-logo', width: 120)
.salary-type.col-auto.order-sm-3
span.salary-range
= @job.salary
span.badge.badge-success
= @job.job_type
.content.col
h5.title
= @job.title
ul.meta
li
strong.text-primary
= @job.company.name
li
i.fa.fa-map-marker
= show_location(city_list)
.job-details-body
h6.mb-3
| Job Description
= @job.description.html_safe
h6.mb-3.mt-4
| Requirement
= @job.requirement.html_safe
h6.mb-3.mt-4
| Benefits
ul
- @job.benefit.split('---').each do |benefit|
li.list-unstyled.col-4.text-secondary
= benefit
h6.mb-3.mt-4
| Other info
ul
- @job.other_info.split('---').each do |info|
li.text-secondary
= info
.col-lg-4.col-12.mb-5
.sidebar-wrap
.sidebar-widget
.inner
.row.m-n2
.col-xl-auto.col-lg-12.col-sm-auto.col-12.p-2
/ a.d-block.btn.btn-outline-secondary[href="#"]
/ i.fa.fa-heart-o.mr-1
/ | Save Job
- if user_signed_in? && current_user.favorite?(@job)
= render 'shared/unfavorite', 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
small
| The
= link_to 'VenJob', root_path
| by Mai Hoàng Thái Hà
nav
ul
li
= link_to 'About', '#'
li
= link_to 'Contact', '#'
\ No newline at end of file
/ footer.footer
/ small
/ | The
/ = link_to 'VenJob', root_path
/ | by Mai Hoàng Thái Hà
/ nav
/ ul
/ li
/ = link_to 'About', '#'
/ li
/ = link_to 'Contact', '#'
.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
.container
= link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'),
- root_path
nav
ul.nav.navbar-nav.navbar-right.text-light
- if user_signed_in?
li
= link_to "Apply jobs", apply_jobs_path
li
= link_to "History", history_jobs_path
li
= link_to "Favorite", favorite_jobs_path
li
= link_to "Profile", user_profile_path
li
= link_to "Log out", destroy_user_session_path, method: :delete
- elsif admin_signed_in?
li
= link_to "Applies job", admin_applies_jobs_path
li
= link_to "Profile", '#'
li
= link_to "Log out", destroy_admin_session_path, method: :delete
- else
/ header.navbar.navbar-fixed-top.navbar-inverse
/ .container
/ = link_to image_tag('logo.png', alt: 'Zigexn logo', width: '150'),
/ - root_path
/ nav
/ ul.nav.navbar-nav.navbar-right.text-light
/ - if user_signed_in?
/ li
/ = link_to "Apply jobs", apply_jobs_path
/ li
/ = link_to "History", history_jobs_path
/ li
/ = link_to "Favorite", favorite_jobs_path
/ li
/ = link_to "Profile", user_profile_path
/ li
/ = link_to "Log out", destroy_user_session_path, method: :delete
/ - elsif admin_signed_in?
/ li
/ = link_to "Applies job", admin_applies_jobs_path
/ li
/ = link_to "Profile", '#'
/ li
/ = link_to "Log out", destroy_admin_session_path, method: :delete
/ - else
li
= link_to "Admin", admin_login_path
li
= link_to "Log in", login_path
li
= link_to "Sign up", signup_path
\ No newline at end of file
= link_to "Sign up", signup_path
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
= yield(:head)
body
= render 'layouts/header'
.container-fluid style ="min-height:80vh;"
.flash
- flash.each do |message_type, message|
div class=("text-center alert alert-#{message_type}") = message
= yield
= render 'layouts/footer'
\ No newline at end of file
div class=("m-0 text-center alert alert-#{message_type}")
= message
.text-center
a.btn-close close
= yield
= render 'layouts/footer'
= javascript_pack_tag 'main'
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,
remote: true,
class: 'btn btn-primary'
| Favorite
class: 'd-block btn btn-outline-secondary' do
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
.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
.section.section-padding
.container
.job-list-toolbar
.page-info.p-2
= page_entries_info jobs
.job-list-wrap
= form_with(url: apply_job_path, method: :get) do |f|
- jobs.each do |item|
.row
.col-2.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}"
.col-10
= link_to item.job, class: 'job-list' do
.company-logo.col-auto
= image_tag('company-logo', width: '120')
.salary-type.col-auto.order-sm-3
span.salary-range
= item.job.salary
span.badge.badge-success
= item.job.job_type
.content.col
h6.title
= item.job.title
ul.meta
li
strong.text-primary
= item.job.company.name
li
i.fa.fa-map-marker
- city_list = item.job.cities
= show_location(item.job.cities)
.d-flex.justify-content-center.my-5
= f.submit 'Apply job', class: 'btn btn-primary w-50'
ul.pagination.pagination-center.mt-5
= 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
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