page ID4

parent 5aa84058
Pipeline #1376 failed with stages
in 0 seconds
...@@ -8,6 +8,9 @@ gem 'rails', '~> 6.1.3', '>= 6.1.3.2' ...@@ -8,6 +8,9 @@ gem 'rails', '~> 6.1.3', '>= 6.1.3.2'
gem 'bootstrap', '~> 5.0.1' gem 'bootstrap', '~> 5.0.1'
gem 'nokogiri', '~> 1.11', '>= 1.11.7' gem 'nokogiri', '~> 1.11', '>= 1.11.7'
gem 'slim-rails' gem 'slim-rails'
gem 'kaminari', '~> 1.2', '>= 1.2.1', :git => 'https://github.com/kaminari/kaminari'
gem 'friendly_id', '~> 5.4', '>= 5.4.2'
gem 'babosa'
# Use sqlite3 as the database for Active Record # Use sqlite3 as the database for Active Record
gem 'mysql2', '~> 0.5.3' gem 'mysql2', '~> 0.5.3'
# Use Puma as the app server # Use Puma as the app server
......
GIT
remote: https://github.com/kaminari/kaminari
revision: 45f13dbdaa98be3733ffe6b0e8e948da6919f116
specs:
kaminari (1.2.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.2.1)
kaminari-activerecord (= 1.2.1)
kaminari-core (= 1.2.1)
kaminari-actionview (1.2.1)
actionview
kaminari-core (= 1.2.1)
kaminari-activerecord (1.2.1)
activerecord
kaminari-core (= 1.2.1)
kaminari-core (1.2.1)
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
...@@ -64,6 +81,7 @@ GEM ...@@ -64,6 +81,7 @@ GEM
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
autoprefixer-rails (10.2.5.1) autoprefixer-rails (10.2.5.1)
execjs (> 0) execjs (> 0)
babosa (1.0.4)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.7.5) bootsnap (1.7.5)
msgpack (~> 1.0) msgpack (~> 1.0)
...@@ -88,6 +106,8 @@ GEM ...@@ -88,6 +106,8 @@ GEM
erubi (1.10.0) erubi (1.10.0)
execjs (2.8.1) execjs (2.8.1)
ffi (1.15.3) ffi (1.15.3)
friendly_id (5.4.2)
activerecord (>= 4.0.0)
globalid (0.4.2) globalid (0.4.2)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
i18n (1.8.10) i18n (1.8.10)
...@@ -219,11 +239,14 @@ PLATFORMS ...@@ -219,11 +239,14 @@ PLATFORMS
x86_64-linux x86_64-linux
DEPENDENCIES DEPENDENCIES
babosa
bootsnap (>= 1.4.4) bootsnap (>= 1.4.4)
bootstrap (~> 5.0.1) bootstrap (~> 5.0.1)
byebug byebug
capybara (>= 3.26) capybara (>= 3.26)
friendly_id (~> 5.4, >= 5.4.2)
jbuilder (~> 2.7) jbuilder (~> 2.7)
kaminari (~> 1.2, >= 1.2.1)!
listen (~> 3.3) listen (~> 3.3)
mysql2 (~> 0.5.3) mysql2 (~> 0.5.3)
nokogiri (~> 1.11, >= 1.11.7) nokogiri (~> 1.11, >= 1.11.7)
......
...@@ -39,3 +39,7 @@ ...@@ -39,3 +39,7 @@
font-weight: 500; font-weight: 500;
font-size: 20px; font-size: 20px;
} }
.form {
width: 700px
}
\ No newline at end of file
...@@ -3,4 +3,9 @@ class CityController < ApplicationController ...@@ -3,4 +3,9 @@ class CityController < ApplicationController
@cities_vietnam = City.cities_by_region(City::REGION_VN_ID) @cities_vietnam = City.cities_by_region(City::REGION_VN_ID)
@cities_international = City.cities_by_region(City::REGION_INTERNATIONAL_ID) @cities_international = City.cities_by_region(City::REGION_INTERNATIONAL_ID)
end end
def show
@city = City.find(params[:slug])
@jobs = @city.jobs.order(created_at: :desc).page(params[:page]).per(20)
end
end end
\ No newline at end of file
...@@ -2,4 +2,9 @@ class IndustryController < ApplicationController ...@@ -2,4 +2,9 @@ class IndustryController < ApplicationController
def list_industry def list_industry
@industry_list = Industry.industry_list @industry_list = Industry.industry_list
end end
def show
@industry = Industry.find(params[:slug])
@jobs = @industry.jobs.order(created_at: :desc).page(params[:page]).per(20)
end
end end
\ No newline at end of file
class JobsController < ApplicationController
def search
@search = Job.search do
keywords(params[:search])
end
end
end
module JobsHelper
end
...@@ -7,4 +7,9 @@ class City < ApplicationRecord ...@@ -7,4 +7,9 @@ class City < ApplicationRecord
REGION_INTERNATIONAL_ID = 2 REGION_INTERNATIONAL_ID = 2
scope :top_cities, -> { joins(:jobs).group(:name).order('count_all DESC').count.take(LATEST_CITY_NUMBER) } scope :top_cities, -> { joins(:jobs).group(:name).order('count_all DESC').count.take(LATEST_CITY_NUMBER) }
scope :cities_by_region, ->(value) { joins(:jobs).group(:name).having('count_all >= ?', 1).where('region_id = ?', value).order('count_all DESC').count } scope :cities_by_region, ->(value) { joins(:jobs).group(:name).having('count_all >= ?', 1).where('region_id = ?', value).order('count_all DESC').count }
extend FriendlyId
friendly_id :name, use: %i[slugged finders]
def normalize_friendly_id(string)
string.to_s.to_slug.normalize(transliterations: :vietnamese).to_s
end
end end
\ No newline at end of file
class Company < ApplicationRecord class Company < ApplicationRecord
has_many :jobs has_many :jobs, dependent: :destroy
has_and_belongs_to_many :cities has_and_belongs_to_many :cities
end end
\ No newline at end of file
...@@ -3,4 +3,9 @@ class Industry < ApplicationRecord ...@@ -3,4 +3,9 @@ class Industry < ApplicationRecord
LATEST_INDUSTRY_NUMBER = 9 LATEST_INDUSTRY_NUMBER = 9
scope :top_industries, -> { joins(:jobs).group(:name).order('count_all DESC').count.take(LATEST_INDUSTRY_NUMBER) } scope :top_industries, -> { joins(:jobs).group(:name).order('count_all DESC').count.take(LATEST_INDUSTRY_NUMBER) }
scope :industry_list, -> { joins(:jobs).group(:name).having('count_all >= ?', 1).order('count_all DESC').count } scope :industry_list, -> { joins(:jobs).group(:name).having('count_all >= ?', 1).order('count_all DESC').count }
extend FriendlyId
friendly_id :name, use: %i[slugged finders]
def normalize_friendly_id(string)
string.to_s.to_slug.normalize(transliterations: :vietnamese).to_s
end
end end
\ No newline at end of file
class Job < ApplicationRecord class Job < ApplicationRecord
belongs_to :company belongs_to :company
has_many :apply_jobs has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs has_many :history_jobs, dependent: :destroy
has_and_belongs_to_many :industries has_and_belongs_to_many :industries
has_and_belongs_to_many :cities has_and_belongs_to_many :cities
LATEST_JOB_NUMBER = 5 LATEST_JOB_NUMBER = 5
......
class User < ApplicationRecord class User < ApplicationRecord
has_many :apply_jobs has_many :apply_jobs, dependent: :destroy
has_many :favorite_jobs has_many :favorite_jobs, dependent: :destroy
has_many :history_jobs has_many :history_jobs, dependent: :destroy
end end
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
.row.my-3.text-center.fs-5 .row.my-3.text-center.fs-5
- @cities_vietnam.each do |name, amount| - @cities_vietnam.each do |name, amount|
.col-3.p-2.border.mb-1.fw-normal.bg-white .col-3.p-2.border.mb-1.fw-normal.bg-white
= link_to name, "#" = link_to name, city_path(City.find_by(name: name))
p.mb-1 p.mb-1
= amount = amount
#international #international
...@@ -23,6 +23,6 @@ ...@@ -23,6 +23,6 @@
.row.my-3.text-center.fs-5 .row.my-3.text-center.fs-5
- @cities_international.each do |name, amount| - @cities_international.each do |name, amount|
.col-3.p-2.border.mb-1.fw-normal.bg-white .col-3.p-2.border.mb-1.fw-normal.bg-white
= link_to name, "#" = link_to name, city_path(City.find_by(name: name))
p.mb-1 p.mb-1
= amount = amount
\ No newline at end of file
- provide :title, 'Jobs'
= render 'jobs/search'
= render 'jobs/job_list'
\ No newline at end of file
...@@ -6,6 +6,6 @@ ...@@ -6,6 +6,6 @@
.row.my-3.text-center.fs-5 .row.my-3.text-center.fs-5
- @industry_list.each do |name, amount| - @industry_list.each do |name, amount|
.col-3.p-2.border.mb-1.fw-normal.bg-white .col-3.p-2.border.mb-1.fw-normal.bg-white
= link_to name, "#" = link_to name, industry_path(Industry.friendly.find_by(name: name))
p.mb-1 p.mb-1
= amount = amount
\ No newline at end of file
- provide :title, 'Jobs'
= render 'jobs/search'
= render 'jobs/job_list'
\ No newline at end of file
.container
h6.offset-md-4
= paginate @jobs, window: 1
.job-list
- @jobs.each do |job|
.card.my-3
.card-body.text-dark
h5.mb-1
= link_to job.title, "#"
p.mb-1
= link_to job.company.name, "#"
p.mb-1
i.fas.fa-dollar-sign.m-1
| Lương:
= job.salary
p.mb-1
i.fas.fa-map-marker-alt.m-1
= link_to job.cities.map(&:name).uniq.join(' | '), "#"
p.mb-1
= truncate(job.overview, length: 250)
h6.offset-md-4.px-5
= page_entries_info @jobs
h6.offset-md-4
= paginate @jobs, window: 1
\ No newline at end of file
.search.p-3.offset-md-2
= form_with(url: '/search', method: 'get', local: true) do
= text_field_tag :search, params[:search], placeholder: "Search", class: "form"
= submit_tag "Search", name: nil, class: 'btn-primary'
li.page-item
= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link'
li.page-item.disabled
= link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link'
li.page-item
= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link'
li.page-item
= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link'
- if page.current?
li.page-item.active
= content_tag :a, page, data: { remote: remote }, rel: page.rel, class: 'page-link'
- else
li.page-item
= link_to page, url, remote: remote, rel: page.rel, class: 'page-link'
= paginator.render do
nav
ul.pagination
== first_page_tag unless current_page.first?
== prev_page_tag unless current_page.first?
- each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window?
== page_tag page
- elsif !page.was_truncated?
== gap_tag
== next_page_tag unless current_page.last?
== last_page_tag unless current_page.last?
li.page-item
= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link'
...@@ -3,11 +3,8 @@ ...@@ -3,11 +3,8 @@
h3.p-2 h3.p-2
| Total: | Total:
= pluralize(@total_job, 'job') = pluralize(@total_job, 'job')
= render 'jobs/search'
.container .container
.input-group.py-3
input.form-control.rounded[type="search" placeholder="Search" aria-label="Search" aria-describedby="search-addon"]
button.btn.btn-outline-primary[type="button"]
| Search
h4.py-4 h4.py-4
| Latest Jobs | Latest Jobs
- @jobs.each do |job| - @jobs.each do |job|
...@@ -23,13 +20,13 @@ h3.p-2 ...@@ -23,13 +20,13 @@ h3.p-2
= job.salary = job.salary
p.mb-1 p.mb-1
i.fas.fa-map-marker-alt.m-1 i.fas.fa-map-marker-alt.m-1
= link_to job.cities.map(&:name).join(', '), "#" = link_to job.cities.map(&:name).uniq.join(' | '), "#"
h4 h4
| Top Cities | Top Cities
.row.my-3.text-center.fs-5 .row.my-3.text-center.fs-5
- @cities.each do |name, amount| - @cities.each do |name, amount|
.col-4.p-2.border.mb-1.fw-normal.bg-white .col-4.p-2.border.mb-1.fw-normal.bg-white
= link_to name, "#" = link_to name, city_path(City.find_by(name: name))
p.mb-1 p.mb-1
= amount = amount
.d-flex.flex-row-reverse. .d-flex.flex-row-reverse.
...@@ -39,7 +36,7 @@ h3.p-2 ...@@ -39,7 +36,7 @@ h3.p-2
.row.my-3.text-center.fs-5 .row.my-3.text-center.fs-5
- @industries.each do |name, amount| - @industries.each do |name, amount|
.col-4.p-2.border.mb-1.fw-normal.bg-white .col-4.p-2.border.mb-1.fw-normal.bg-white
= link_to name, "#" = link_to name, industry_path(Industry.find_by(name: name))
p.mb-1 p.mb-1
= amount = amount
.d-flex.flex-row-reverse .d-flex.flex-row-reverse
......
# frozen_string_literal: true
Kaminari.configure do |config|
# config.default_per_page = 25
# config.max_per_page = nil
# config.window = 4
# config.outer_window = 0
# config.left = 0
# config.right = 0
# config.page_method_name = :page
# config.param_name = :page
# config.max_pages = nil
# config.params_on_first_page = false
end
...@@ -30,4 +30,19 @@ ...@@ -30,4 +30,19 @@
# available at https://guides.rubyonrails.org/i18n.html. # available at https://guides.rubyonrails.org/i18n.html.
en: en:
hello: "Hello world" views:
pagination:
first: "&laquo; First"
last: "Last &raquo;"
previous: "&lsaquo; Prev"
next: "Next &rsaquo;"
truncate: "&hellip;"
helpers:
page_entries_info:
one_page:
display_entries:
zero: "No %{entry_name} found"
one: "Displaying <b>1</b> %{entry_name}"
other: "Displaying <b>all %{count}</b> %{entry_name}"
more_pages:
display_entries: "Displaying %{entry_name} <b>%{first}&nbsp;-&nbsp;%{last}</b> of <b>%{total}</b> in total"
...@@ -2,4 +2,7 @@ Rails.application.routes.draw do ...@@ -2,4 +2,7 @@ Rails.application.routes.draw do
root 'top#home' root 'top#home'
get 'cities', to: 'city#list_city' get 'cities', to: 'city#list_city'
get 'industries', to: 'industry#list_industry' get 'industries', to: 'industry#list_industry'
scope '/jobs' do
resources :city, :industry, param: :slug
end
end end
\ No newline at end of file
class AddSlugToCities < ActiveRecord::Migration[6.1]
def change
add_column :cities, :slug, :string
add_index :cities, :slug, unique: true
end
end
class AddSlugIndustries < ActiveRecord::Migration[6.1]
def change
add_column :industries, :slug, :string
add_index :industries, :slug, unique: true
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_07_23_035105) do ActiveRecord::Schema.define(version: 2021_07_31_111344) do
create_table "apply_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "apply_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
...@@ -27,7 +27,9 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do ...@@ -27,7 +27,9 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do
t.string "name" t.string "name"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.string "slug"
t.index ["region_id"], name: "index_cities_on_region_id" t.index ["region_id"], name: "index_cities_on_region_id"
t.index ["slug"], name: "index_cities_on_slug", unique: true
end end
create_table "cities_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "cities_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
...@@ -66,6 +68,17 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do ...@@ -66,6 +68,17 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do
t.index ["user_id"], name: "index_favorite_jobs_on_user_id" t.index ["user_id"], name: "index_favorite_jobs_on_user_id"
end end
create_table "friendly_id_slugs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false
t.string "sluggable_type", limit: 50
t.string "scope"
t.datetime "created_at"
t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true, length: { slug: 70, scope: 70 }
t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type", length: { slug: 140 }
t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
end
create_table "history_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "history_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "user_id", null: false t.bigint "user_id", null: false
t.bigint "job_id", null: false t.bigint "job_id", null: false
...@@ -79,6 +92,8 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do ...@@ -79,6 +92,8 @@ ActiveRecord::Schema.define(version: 2021_07_23_035105) do
t.string "name" t.string "name"
t.datetime "created_at", precision: 6, null: false t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.string "slug"
t.index ["slug"], name: "index_industries_on_slug", unique: true
end end
create_table "industries_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| create_table "industries_jobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
......
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