Commit b56289bd by Trong Huu Nguyen

Merge branch 'dhp_solr' into 'development'

[Review] Solr feature

See merge request !5
parents efca5cdb acbd7d6e
......@@ -22,4 +22,7 @@
/public/uploads/*
# Ignore database config file
/config/database.yml
\ No newline at end of file
/config/database.yml
config/settings.local.yml
config/settings/*.local.yml
config/environments/*.local.yml
......@@ -36,6 +36,8 @@ gem 'carrierwave', '~> 1.0'
gem 'mini_magick'
# bootstrap-sass is a Sass-powered version of Bootstrap 3
gem 'bootstrap-sass', '~> 3.3.6'
# Config helps you easily manage environment specific settings in an easy and usable manner.
gem 'config'
# Faker, a port of Data::Faker from Perl, is used to easily generate fake data: names, addresses, phone numbers, etc.
gem 'faker', '~> 1.6', '>= 1.6.3'
# Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 4+
......@@ -58,6 +60,8 @@ gem 'toastr-rails', '~> 1.0', '>= 1.0.3'
# (or more often navigation item)
# is selected based on the current page or other arbitrary condition
gem 'active_link_to', '~> 1.0', '>= 1.0.4'
# RSolr aims to provide a simple and extensible library for working with Solr
gem 'rsolr', '~> 2.0', '>= 2.0.2'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
......
......@@ -76,7 +76,11 @@ GEM
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
config (1.4.0)
activesupport (>= 3.0)
deep_merge (~> 1.1.1)
connection_pool (2.2.1)
deep_merge (1.1.1)
devise (4.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
......@@ -87,6 +91,8 @@ GEM
execjs (2.7.0)
faker (1.6.6)
i18n (~> 0.5)
faraday (0.12.1)
multipart-post (>= 1.2, < 3)
ffi (1.9.18)
font-awesome-rails (4.7.0.2)
railties (>= 3.2, < 5.2)
......@@ -132,6 +138,7 @@ GEM
mini_portile2 (2.2.0)
minitest (5.10.2)
multi_json (1.12.1)
multipart-post (2.0.0)
mysql2 (0.4.6)
nio4r (2.1.0)
nokogiri (1.8.0)
......@@ -187,6 +194,9 @@ GEM
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rsolr (2.0.2)
builder (>= 2.1.2)
faraday
rubocop (0.49.1)
parallel (~> 1.10)
parser (>= 2.3.3.1, < 3.0)
......@@ -262,6 +272,7 @@ DEPENDENCIES
capybara (~> 2.13)
carrierwave (~> 1.0)
coffee-rails (~> 4.2)
config
devise (~> 4.3)
faker (~> 1.6, >= 1.6.3)
font-awesome-rails (~> 4.7, >= 4.7.0.2)
......@@ -275,6 +286,7 @@ DEPENDENCIES
puma (~> 3.7)
rails (~> 5.1.1)
rails-assets-bootstrap-touchspin!
rsolr (~> 2.0, >= 2.0.2)
rubocop (~> 0.49.1)
sass-rails (~> 5.0)
selenium-webdriver
......
(function($) {
// Vertical Spinner - Touchspin - Product Details Quantity input
if ( $.fn.TouchSpin ) {
$('#product_quantity').TouchSpin({
$('.vertical-spinner').TouchSpin({
verticalbuttons: true
});
$('.qty-input').TouchSpin();
......
(function($) {
toastr.options.closeButton = true;
// Search Dropdown Toggle
$('.search-toggle').on('click', function (e) {
$('.header-search-wrapper').toggleClass('open');
e.preventDefault();
});
}).apply(this, [jQuery]);
\ No newline at end of file
......@@ -124,11 +124,23 @@ a {
clear: both;
}
@media (max-width: 991px) {
#header .header-row {
display: block;
}
}
#header .header-column {
display: table-cell;
vertical-align: middle;
}
@media (max-width: 991px) {
#header .header-column {
display: block;
}
}
#header .header-column .row {
margin: 0;
}
......@@ -137,6 +149,247 @@ a {
display: block;
clear: right;
}
#header .header-container {
padding-top: 28px;
padding-bottom: 28px;
position: relative;
display: table;
}
#header .header-container.header-nav {
padding: 0;
}
#header .header-nav-main nav {
height: 50px;
border-radius: 0;
background-color: #54555e;
}
#header .header-nav-main nav > ul > li > a.dropdown-toggle {
-webkit-transition: none;
-moz-transition: none;
transition: none;
color: #fff;
padding: 15px 20px 15px 20px;
}
#header .header-nav-main nav > ul > li > a.dropdown-toggle:after {
font-size: inherit;
content: "\f107";
right: 16px;
top: 15px;
}
#header .header-nav-main nav > ul > li > a {
-webkit-transition: none;
-moz-transition: none;
transition: none;
color: #fff;
padding: 15px 20px;
text-transform: uppercase;
}
#header .header-nav-main nav > ul > li:hover > a,
#header .header-nav-main nav > ul > li:hover > a.dropdown-toggle, #header .header-nav-main nav > ul > li.open > a,
#header .header-nav-main nav > ul > li.open > a.dropdown-toggle, #header .header-nav-main nav > ul > li.active > a,
#header .header-nav-main nav > ul > li.active > a.dropdown-toggle, #header .header-nav-main nav > ul > li.dropdown:hover > a,
#header .header-nav-main nav > ul > li.dropdown:hover > a.dropdown-toggle, #header .header-nav-main nav > ul > li.dropdown.open > a,
#header .header-nav-main nav > ul > li.dropdown.open > a.dropdown-toggle, #header .header-nav-main nav > ul > li.dropdown.active > a,
#header .header-nav-main nav > ul > li.dropdown.active > a.dropdown-toggle {
padding-bottom: 19px;
}
#header .header-nav-main nav > ul > li.dropdown .dropdown-menu {
border-left: none;
border-right: none;
border-bottom: none;
}
#header .header-nav-main nav > ul > li.dropdown .dropdown-menu li a {
border-bottom: none;
}
#header .header-nav-main nav > ul > li.dropdown .dropdown-menu li.dropdown-submenu > a:after {
content: "\f105";
font-family: FontAwesome;
font-size: inherit;
border: none;
margin: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu {
border-radius: 0 0 0 0;
padding: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content {
padding: 10px 20px 20px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol {
list-style: none;
margin: 0;
padding: 5px 0;
left: 100%;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul li,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol li {
line-height: 22px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li a,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li a, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul li a,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol li a {
padding: 0;
margin: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li a:hover, #header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li a:focus,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li a:hover,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li a:focus, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul li a:hover, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul li a:focus,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol li a:hover,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol li a:focus {
text-decoration: underline;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li:hover a,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li:hover a, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ul li:hover a,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content ol li:hover a {
background-color: transparent;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .dropdown-mega-sub-title, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .dropdown-mega-sub-title {
display: block;
font-size: 14px;
font-weight: 600;
padding: 0;
text-transform: uppercase;
line-height: 1.5;
margin-top: 10px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .cat-img, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .cat-img {
display: block;
padding: 0;
margin-top: 15px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .cat-img img, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .cat-img img {
display: block;
max-width: 100%;
height: auto;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .dropdown-mega-top, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .dropdown-mega-top {
padding: 4px 0 8px;
border-bottom: 1px solid #eee;
color: #000;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .dropdown-mega-top a,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .dropdown-mega-top span, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .dropdown-mega-top a,
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .dropdown-mega-top span {
font-size: 12px;
font-weight: 400;
color: #000;
text-transform: uppercase;
padding: 0;
margin-right: 15px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .dropdown-mega-top span, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .dropdown-mega-top span {
font-weight: 700;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area {
position: relative;
text-align: center;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area img, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area img {
display: inline-block;
max-width: 100%;
height: auto;
margin: 20px auto 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header {
position: absolute;
top: -35px;
left: -15px;
text-align: left;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header h3, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header h3 {
font-size: 23px;
font-weight: 600;
color: #fff;
background-color: #2e2e2e;
line-height: 1;
padding: 6px 50px 6px 8px;
margin-bottom: 15px;
text-transform: uppercase;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn {
font-size: 13px;
padding: 5px 7px 5px 8px;
color: #fff;
border: 0;
font-size: 13px;
min-width: 109px;
text-align: center;
text-transform: uppercase;
border-radius: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn:hover, #header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn:focus, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn:hover, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn:focus {
opacity: 0.9;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn i, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area .menu-banner-header .btn i {
margin-left: 4px;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content .menu-banner-area p, #header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu .dropdown-mega-content .menu-banner-area p {
position: absolute;
bottom: 8px;
width: 60%;
text-align: center;
left: 50px;
line-height: 14px;
font-size: 13px;
margin-bottom: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega-small > .dropdown-menu {
width: 600px;
}
#header .header-nav-main nav > ul > li.dropdown-mega-small .mega-banner-bg img {
position: absolute;
right: 10px;
top: -10px;
height: 273px;
width: auto;
max-width: none;
z-index: -1;
border-radius: 0;
}
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ul li,
#header .header-nav-main nav > ul > li.dropdown-mega > .dropdown-menu .dropdown-mega-content ol li {
line-height: 23px;
}
#header .header-nav-main nav > ul > li:hover > a, #header .header-nav-main nav > ul > li.open > a, #header .header-nav-main nav > ul > li.active > a {
color: #fff;
background-color: #000;
}
#header .header-nav-main nav > ul > li:hover > a:hover, #header .header-nav-main nav > ul > li:hover > a:focus, #header .header-nav-main nav > ul > li.open > a:hover, #header .header-nav-main nav > ul > li.open > a:focus, #header .header-nav-main nav > ul > li.active > a:hover, #header .header-nav-main nav > ul > li.active > a:focus {
color: #fff;
background-color: #000;
}
#header .header-nav-main nav > ul > li .dropdown-menu > li:hover > a {
background-color: #f4f4f4;
}
#header .header-nav-main nav > ul > li .dropdown-menu > li:hover > a:hover, #header .header-nav-main nav > ul > li .dropdown-menu > li:hover > a:focus {
background-color: #f4f4f4;
}
@media (min-width: 992px) {
#header .header-nav {
display: block !important;
}
#header .header-nav-main {
margin-top: 0;
float: none;
min-height: 54px;
border-bottom: 4px solid #3f4048;
}
}
#header .header-container.header-nav {
padding: 0;
}
@media (max-width: 991px) {
#header .header-container {
display: block;
}
#header .header-nav, #header .header-nav-main {
display: none;
}
}
#header .cart-area {
float: right;
......@@ -623,7 +876,7 @@ a {
text-decoration: none;
}
.product-actions a.addtocart {
.product-actions .addtocart {
color: #333;
background-color: #fff;
font-size: 14px;
......@@ -633,88 +886,17 @@ a {
border: 1px solid #ccc;
}
.product-actions a.addtocart i {
.product-actions .addtocart i {
font-size: 15px;
margin-right: 2px;
}
.product:hover .product-actions a.addtocart {
.product:hover .product-actions .addtocart {
background-color: #000;
border-color: #000;
color: #fff;
}
.product-actions a.addtocart.outofstock {
padding: 0 10px;
cursor: default;
}
.product:hover .product-actions a.addtocart.outofstock {
color: #333 !important;
background-color: #fff !important;
border-color: #ccc !important;
}
.product-actions a.addtowishlist, .product-actions a.comparelink, .product-actions a.quickview {
font-size: 17px;
height: 32px;
width: 32px;
line-height: 32px;
background-color: transparent;
visibility: hidden;
opacity: 0;
}
.hide-addtolinks .product-actions a.addtowishlist, .hide-addtolinks .product-actions a.comparelink, .hide-addtolinks .product-actions a.quickview {
display: none;
}
.product-actions a.addtowishlist {
right: -37px;
color: #ed4949;
border: 1px solid #ed4949;
}
.product-actions a.addtowishlist:hover {
color: #fff;
background-color: #ed4949;
}
.product:hover .product-actions a.addtowishlist {
visibility: visible;
opacity: 1;
right: 0;
}
.product-actions a.comparelink {
left: -37px;
color: #52b9b5;
border: 1px solid #52b9b5;
}
.product-actions a.comparelink:hover {
color: #fff;
background-color: #52b9b5;
}
.product:hover .product-actions a.comparelink {
visibility: visible;
opacity: 1;
left: 0;
}
.product-actions a.quickview {
visibility: visible;
opacity: 1;
color: #000;
border: 1px solid #000;
}
.product-actions a.quickview:hover {
color: #fff;
background-color: #000;
}
.product.product-list:after {
content: '';
display: table;
......
......@@ -92,15 +92,6 @@ html .btn-primary:active:focus {
#header .header-logo img {
margin: 0 24px 0 0;
}
#header .header-container {
padding-top: 28px;
padding-bottom: 28px;
position: relative;
display: table;
}
#header .header-container.header-nav {
padding: 0;
}
#header .cart-area {
float: right;
vertical-align: middle;
......@@ -171,7 +162,6 @@ header .header-search {
position: relative;
width: 100%;
min-width: 250px;
padding-right: 170px;
background-color: #fff;
}
#header .header-search .header-search-wrapper.open {
......@@ -278,6 +268,9 @@ header .header-search {
color: #000;
background-color: transparent;
}
#header .header-nav-main nav > ul > li > a {
border-radius: 0;
}
.panel-default>.panel-heading {
color: #333;
background-color: #f5f5f5;
......
class SearchController < ApplicationController
before_action :set_search_result, only: :show
# GET /search
def show
@products = if @search_result.is_a?(Array)
Kaminari.paginate_array(@search_result).page(params[:page]).per(5)
else
@search_result.page(params[:page]).per(5)
end
end
private
def set_search_result
@search_result = if params[:q].present?
Search.new(params[:q]).products
else
Product.all
end
end
end
\ No newline at end of file
class StaticPagesController < ApplicationController
def index
@latest_products = Product.page(params[:page]).per(10)
@latest_products = Product.page(params[:page]).per(5)
# @TODO: Get recommended products
@recommended_products = Product.last(6)
# session.clear
......
module SearchHelper
def render_search_result(search_result)
if search_result.blank?
render html: 'Sorry! There are no products matched your query'
else
render(partial: 'products/product_list',
locals: { products: search_result })
end
end
end
\ No newline at end of file
......@@ -16,7 +16,7 @@ class Cart
real_quantity = product_quantity(product_id, quantity)
return false unless product_is_in_stock?(product_id, real_quantity)
if product_item_exist?(product_id)
@cart[product_id.to_s][:quantity.to_s] += real_quantity.to_i
@cart[product_id.to_s][:quantity.to_s] = real_quantity.to_i
else
@cart[product_id.to_s] = { quantity: real_quantity.to_i }
end
......
class Search
def initialize(search_query)
@solr = SolrSearch.new
@search_query = search_query
end
def products
@solr.search_for(@search_query)
filter_products(@solr.docs)
end
private
def filter_products(products)
product_ids = products.map { |product| product[:id.to_s] }
Product.find(product_ids)
end
end
\ No newline at end of file
require 'rsolr'
class SolrSearch
attr_accessor :rsolr
def initialize
@rsolr = RSolr.connect url: Settings.rsolr.address
@response = nil
end
def search_for(search_query)
search_query ||= ''
@response = rsolr.get 'select', params: { q: sanitize_query(search_query) }
end
def docs
@response['response']['docs']
end
def sanitize_query(query)
query.gsub(/[^0-9A-Za-z]/, '')
end
end
\ No newline at end of file
......@@ -5,7 +5,7 @@
<td class="product-image-td"></td>
<td class="product-name-td">
<h2 class="product-name">
<%= link_to product_item[:product].title, product_item_url(product_item[:product]) %>
<%= link_to product_item[:product].title, product_url(product_item[:product]) %>
</h2>
</td>
<td><%= number_to_currency(product_item[:product].price) %></td>
......
......@@ -36,15 +36,11 @@
</a>
</div>
</div>
<div class="header-search">
</div>
<%= render 'layouts/header/search_form' %>
</div>
</div>
</div>
</div>
<div class="header-container header-nav">
</div>
<%= render 'layouts/header/main_nav' %>
</div>
</header>
\ No newline at end of file
......@@ -5,6 +5,7 @@
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= stylesheet_link_tag 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800%7CShadows+Into+Light' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
......
<div class="header-container header-nav">
<div class="container">
<div class="header-nav-main">
<nav>
<ul id="mainNav" class="nav nav-pills">
<%= active_link_to 'Home', root_url, wrap_tag: :li, active: :exclusive %>
</ul>
</nav>
</div>
</div>
</div>
\ No newline at end of file
<div class="header-search">
<a href="#" class="search-toggle"><i class="fa fa-search"></i></a>
<%= form_tag search_result_path, method: :get do %>
<div class="header-search-wrapper">
<%= text_field_tag :q, params[:q], class: 'form-control', placeholder: 'Search...' %>
<%= button_tag raw('<i class="fa fa-search"></i>'), class: 'btn btn-default' %>
</div>
<% end %>
</div>
\ No newline at end of file
......@@ -26,7 +26,7 @@
<div class="col-md-12">
<div class="form-group">
<%= f.label :quantity %>
<%= f.number_field :quantity, class: "form-control" %>
<%= f.number_field :quantity, class: "form-control vertical-spinner" %>
</div>
</div>
......
......@@ -30,7 +30,7 @@
<div class="product-detail-qty">
<%= number_field_tag :product_quantity, 1, min: 0, class: 'vertical-spinner' %>
</div>
<%= submit_tag 'Add to cart', class: 'addtocart' %>
<%= button_tag raw(fa_icon('shopping-cart', text: 'Add to cart')), class: 'addtocart' %>
<% end %>
</div>
</div>
......
<div class="product-actions">
<%= form_tag cart_add_product_item_path(product.id), remote: true do %>
<%= hidden_field_tag :product_quantity, 1 %>
<%= button_tag fa_icon('shopping-cart', text: 'Add to cart'), class: 'addtocart' %>
<% end %>
</div>
\ No newline at end of file
......@@ -12,6 +12,7 @@
<div class="product-price-box">
<span class="product-price"><%= number_to_currency(product.price) %></span>
</div>
<%= render partial: 'products/product_action', locals: { product: product } %>
</div>
</div>
</li>
......
......@@ -11,11 +11,12 @@
<%= link_to fa_icon('pencil'), edit_product_path(product) if product.belongs_to_user?(current_user) %>
</h2>
<div class="product-short-desc">
<%= product.description %>
<%= truncate(product.description, length: 300) %>
</div>
<div class="product-price-box">
<span class="product-price"><%= number_to_currency(product.price) %></span>
</div>
<%= render partial: 'products/product_action', locals: { product: product } %>
</div>
</div>
</li>
......
<div class="container">
<div class="row">
<div class="col-md-9 col-md-push-3">
<h2 class="h2 heading-primary mt-lg clearfix">
<span>Search result</span>
</h2>
<%= render_search_result(@products) %>
<div class="toolbar-bottom">
<div class="toolbar">
<div class="sorter">
<%= paginate @products, theme: 'bootstrap' %>
</div>
</div>
</div>
</div>
<div class="col-md-3 col-md-pull-9 sidebar shop-sidebar">
<%= render 'shared/sidebar' %>
</div>
</div>
</div>
<tr>
<td><%= link_to "##{product.id}", edit_product_path(product) %></td>
<td class="product-name-td">
<h2 class="product-name">
<%= link_to product.title, product_url(product) %>
</h2>
</td>
<td><%= number_to_currency(product.price) %></td>
<td><%= product.quantity %></td>
<td><%= link_to fa_icon('pencil'), edit_product_path(product) %></td>
</tr>
\ No newline at end of file
<table class="cart-table">
<thead>
<tr>
<th>ID</th>
<th>Product Name</th>
<th>Unit Price</th>
<th>Qty</th>
<th></th>
</tr>
</thead>
<tbody>
<% @products.each do |product| %>
<%= render partial: 'product', locals: { product: product } %>
<% end %>
</tbody>
</table>
\ No newline at end of file
......@@ -4,7 +4,7 @@
<h2 class="h2 heading-primary font-weight-normal">
My Products
</h2>
<%= render partial: 'products/product_list', locals: { products: @products } %>
<%= render 'product_table' %>
<div class="toolbar-bottom">
<div class="toolbar">
<div class="sorter">
......
Config.setup do |config|
# Name of the constant exposing loaded settings
config.const_name = 'Settings'
# Ability to remove elements of the array set in earlier loaded settings file. For example value: '--'.
#
# config.knockout_prefix = nil
# Overwrite arrays found in previously loaded settings file. When set to `false`, arrays will be merged.
#
# config.overwrite_arrays = true
# Load environment variables from the `ENV` object and override any settings defined in files.
#
# config.use_env = false
# Define ENV variable prefix deciding which variables to load into config.
#
# config.env_prefix = 'Settings'
# What string to use as level separator for settings loaded from ENV variables. Default value of '.' works well
# with Heroku, but you might want to change it for example for '__' to easy override settings from command line, where
# using dots in variable names might not be allowed (eg. Bash).
#
# config.env_separator = '.'
# Ability to process variables names:
# * nil - no change
# * :downcase - convert to lower case
#
# config.env_converter = :downcase
# Parse numeric values as integers instead of strings.
#
# config.env_parse_values = true
end
......@@ -20,4 +20,5 @@ Rails.application.routes.draw do
get '/', to: 'users#show', as: 'user_profile'
get '/products', to: 'users#products', as: 'user_products'
end
get '/search', to: 'search#show', as: 'search_result'
end
# RSolr
rsolr:
address: http://localhost:8983/solr/dhp_venshop
\ No newline at end of file
namespace :import_solr_data do
desc "Import product data from database"
task product: :environment do
documents = []
Product.all.each do |product|
documents << { id: product.id, title: product.title, price: product.price }
end
solr_search = SolrSearch.new
solr_search.rsolr.add documents
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment