Commit 7b3c43dc by Hoang Phuc Do

Layout for product items on top page and category page

parent 107dbf62
...@@ -38,7 +38,8 @@ gem 'mini_magick' ...@@ -38,7 +38,8 @@ gem 'mini_magick'
gem 'bootstrap-sass', '~> 3.3.6' gem 'bootstrap-sass', '~> 3.3.6'
# Faker, a port of Data::Faker from Perl, is used to easily generate fake data: names, addresses, phone numbers, etc. # 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' gem 'faker', '~> 1.6', '>= 1.6.3'
# Kaminari is a Scope & Engine based, clean, powerful, agnostic, customizable and sophisticated paginator for Rails 4+
gem 'kaminari', '~> 1.0', '>= 1.0.1'
# Use Capistrano for deployment # Use Capistrano for deployment
# gem 'capistrano-rails', group: :development # gem 'capistrano-rails', group: :development
......
...@@ -81,6 +81,18 @@ GEM ...@@ -81,6 +81,18 @@ GEM
jbuilder (2.7.0) jbuilder (2.7.0)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
multi_json (>= 1.2) multi_json (>= 1.2)
kaminari (1.0.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.0.1)
kaminari-activerecord (= 1.0.1)
kaminari-core (= 1.0.1)
kaminari-actionview (1.0.1)
actionview
kaminari-core (= 1.0.1)
kaminari-activerecord (1.0.1)
activerecord
kaminari-core (= 1.0.1)
kaminari-core (1.0.1)
listen (3.1.5) listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.7)
...@@ -191,6 +203,7 @@ DEPENDENCIES ...@@ -191,6 +203,7 @@ DEPENDENCIES
coffee-rails (~> 4.2) coffee-rails (~> 4.2)
faker (~> 1.6, >= 1.6.3) faker (~> 1.6, >= 1.6.3)
jbuilder (~> 2.5) jbuilder (~> 2.5)
kaminari (~> 1.0, >= 1.0.1)
listen (>= 3.0.5, < 3.2) listen (>= 3.0.5, < 3.2)
mini_magick mini_magick
mysql2 (>= 0.3.18, < 0.5) mysql2 (>= 0.3.18, < 0.5)
......
@charset "UTF-8";
/* ----------- 1.General --------------
--------------------------------------*/
body {
position: relative;
color: #717179;
font: 400 13px/2.15 "Poppins", sans-serif;
background-color: #f4f4f4;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
#wrapper {
width: 100%;
background-color: #ffffff;
}
@media (min-width: 1280px) {
.container {
width: 1200px;
}
}
::-moz-selection {
color: #fff;
background-color: #262634;
}
::selection {
color: #fff;
background-color: #262634;
}
iframe {
border: none;
outline: none;
}
pre {
border: none;
border-radius: 0;
padding: 16px;
background-color: #fff;
}
ul,
ol {
list-style: none;
padding: 0;
margin: 0;
}
a:focus, a:active,
select:focus,
select:active,
input:focus,
input:active,
textarea:focus,
textarea:active,
button:focus,
button:active {
outline: none;
}
hr {
margin: 25px 0;
border: none;
width: 100%;
height: 1px;
background-color: #e9e9ea;
}
/* ----------- 2.Typography -----------
--------------------------------------*/
/* Typography */
h1, .h1,
h2, .h2,
h3, .h3,
h4, .h4,
h5, .h5,
h6, .h6 {
font-weight: 400;
font-family: "Oswald", sans-serif, Arial, sans-serif;
line-height: 1.1;
color: #262634;
margin-top: 0;
margin-bottom: 20px;
letter-spacing: 0.075em;
}
h1 small, .h1 small,
h2 small, .h2 small,
h3 small, .h3 small,
h4 small, .h4 small,
h5 small, .h5 small,
h6 small, .h6 small {
color: inherit;
}
h1, .h1 {
font-size: 26px;
}
h2, .h2 {
font-size: 20px;
}
h3, .h3 {
font-size: 18px;
}
h4, .h4 {
font-size: 16px;
}
h5, .h5 {
font-size: 14px;
}
h6, .h6 {
font-size: 12px;
}
a {
position: relative;
color: #262634;
transition: color 0.4s;
}
a:hover, a:focus {
color: #dc9831;
text-decoration: none;
}
p {
margin-bottom: 20px;
}
blockquote {
position: relative;
padding: 5px 0 5px 35px;
margin: 20px 0;
font-size: 16px;
border-left: 2px solid transparent;
}
blockquote p {
margin-bottom: 12px;
}
blockquote cite {
font-size: 16px;
font-weight: 400;
}
/* ----------- 7.Category --------------
--------------------------------------*/
.category-header {
padding: 25px 0 15px;
}
.category-header h1 {
font-size: 18px;
text-transform: uppercase;
margin-bottom: 8px;
}
.shop-container {
transition: all 0.45s;
margin-bottom: 10px;
}
@media (min-width: 768px) {
.shop-container {
margin-bottom: 30px;
}
}
.shop-container:after {
content: '';
display: table;
clear: both;
}
.shop-container .product-item {
float: left;
width: 100%;
}
.shop-row {
margin-left: -15px;
margin-right: -15px;
}
.shop-row > .shop-container > .product-item {
padding: 0 15px;
}
.shop-row:after {
content: '';
display: table;
clear: both;
}
@media (min-width: 481px) {
.max-col-3 .product-item {
width: 50%;
}
}
@media (min-width: 992px) {
.max-col-3 .product-item {
width: 33.3%;
}
}
/* Product */
.product {
margin-bottom: 20px;
}
.product .product-image-container {
margin-bottom: 23px;
position: relative;
background-color: #f0f0f0;
}
.product .product-title {
font-weight: 500;
font-size: 14px;
font-family: "Poppins", sans-serif;
line-height: 1.7;
letter-spacing: 0.05em;
color: #717179;
margin-bottom: 1px;
}
.product .product-title a {
color: #717179;
}
.product .product-title a:hover, .product .product-title a:focus {
color: #262634;
}
.product r.poduct-price {
font-weight: 500;
font-size: 14px;
line-height: 1.7;
color: #262634;
}
.product .product-image-container img {
display: block;
width: 100%;
height: auto;
}
.products-list li.product {
padding: 15px;
}
.products-list li.product:after {
content: '';
display: table;
clear: both;
}
.products-list li.product .product-image-area {
width: 20%;
float: left;
}
.products-list li.product .product-image-area img {
width: 100%;
}
.products-list li.product .product-details-area {
width: 80%;
float: left;
padding: 0 20px;
margin-top: 10px;
}
.products-list li.product .product-title {
margin-bottom: 0;
}
/* ----------- 8.Product --------------
--------------------------------------*/
class CategoriesController < ApplicationController
def show
@category = Category.find(params[:id])
@products = @category.products.take(6)
end
end
\ No newline at end of file
class ProductsController < ApplicationController
end
\ No newline at end of file
class StaticPagesController < ApplicationController
def index
@latest_products = Product.page(params[:page]).per(10)
# @TODO: Get recommended products
@recommended_products = Product.last(6)
end
end
\ No newline at end of file
module ProductsHelper
def get_product_thumbnail(product, thumbnail_width, thumbnail_height)
if product.image_url.present?
product.image_url
else
"product/placeholder_#{thumbnail_width}x#{thumbnail_height}"
end
end
end
\ No newline at end of file
<div class="row">
<div class="col-md-9 col-md-push-3">
<div class="category-header">
<h2><%= @category.title %></h2>
</div>
<div class="shop-row">
<div class="shop-container">
<ul class="products-list">
<%= render @products %>
</ul>
</div>
</div>
</div>
<!-- End .col-md-9 -->
<div class="col-md-3 col-md-pull-9 sidebar">
<%= render 'shared/sidebar' %>
</div>
</div>
<!-- End .row -->
\ No newline at end of file
<%# Link to the "First" page
- available local variables
url: url to the first page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="first">
<%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, remote: remote %>
</span>
<%# Non-link tag that stands for skipped pages...
- available local variables
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="page gap"><%= t('views.pagination.truncate').html_safe %></span>
<%# Link to the "Last" page
- available local variables
url: url to the last page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="last">
<%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, remote: remote %>
</span>
<%# Link to the "Next" page
- available local variables
url: url to the next page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="next">
<%= link_to_unless current_page.last?, t('views.pagination.next').html_safe, url, rel: 'next', remote: remote %>
</span>
<%# Link showing page number
- available local variables
page: a page object for "this" page
url: url to this page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="page<%= ' current' if page.current? %>">
<%= link_to_unless page.current?, page, url, {remote: remote, rel: page.rel} %>
</span>
<%# The container tag
- available local variables
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
paginator: the paginator that renders the pagination tags inside
-%>
<%= paginator.render do -%>
<nav class="pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| -%>
<% if page.display_tag? -%>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end -%>
<% end -%>
<% unless current_page.out_of_range? %>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
<% end %>
</nav>
<% end -%>
<%# Link to the "Previous" page
- available local variables
url: url to the previous page
current_page: a page object for the currently displayed page
total_pages: total number of pages
per_page: number of items to fetch per page
remote: data-remote
-%>
<span class="prev">
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, rel: 'prev', remote: remote %>
</span>
...@@ -9,6 +9,14 @@ ...@@ -9,6 +9,14 @@
</head> </head>
<body> <body>
<div id="wrapper">
<div class="main">
<div class="container">
<%= yield %> <%= yield %>
</div>
<!-- End .container -->
</div>
<!-- End .main -->
</div>
</body> </body>
</html> </html>
<li class="product product-<%= product.id %>">
<div class="product-image-area">
<a href="#" class="product-image">
<%= image_tag(get_product_thumbnail(product, 170, 204)) %>
</a>
</div>
<div class="product-details-area">
<h2 class="product-title"><%= product.title %></h2>
<div class="product-price-container">
<span class="product-price"><%= product.price %></span>
</div>
<!-- End .product-price-container -->
<div class="product-short-desc"><%= product.description %></div>
</div>
</li>
<!-- End .product -->
\ No newline at end of file
<% @recommended_products.each do |product| %>
<div class="product-item">
<div class="product product-<%= product.id %>">
<div class="product-image-container">
<a href="#" class="product-image">
<%= image_tag(get_product_thumbnail(product, 170, 204)) %>
</a>
</div>
<div class="product-details-area">
<h2 class="product-title"><%= product.title %></h2>
<div class="product-price-container">
<span class="product-price"><%= product.price %></span>
</div>
<!-- End .product-price-container -->
</div>
</div>
<!-- End .product -->
</div>
<% end %>
\ No newline at end of file
<div class="row">
<div class="col-md-9 col-md-push-3">
<div class="category-header">
<h2>Recommended Items</h2>
</div>
<div class="shop-row">
<div class="shop-container max-col-3">
<%= render 'products/recommended' %>
</div>
</div>
<div class="category-header">
<h2>Newest Items</h2>
</div>
<div class="shop-row">
<div class="shop-container">
<ul class="products-list">
<%= render @latest_products %>
</ul>
</div>
</div>
<%= paginate @latest_products %>
</div>
<!-- End .col-md-9 -->
<div class="col-md-3 col-md-pull-9 sidebar">
<%= render 'shared/sidebar' %>
</div>
</div>
<!-- End .row -->
Rails.application.routes.draw do Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'static_pages#index'
resources :categories
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