Commit 0de6c1d2 by Truong Ba Dieu

Responsive in mobile

parent 4b9be94a
......@@ -42,7 +42,7 @@ group :development, :test do
gem 'spring'
end
# gem 'kaminari', '0.16.3'
gem 'will_paginate', '~> 3.0.6'
gem 'font-awesome-sass', '4.3.2.1'
# Bootstrap 3: https://github.com/twbs/bootstrap-sass
......@@ -62,7 +62,14 @@ gem 'rsolr'
gem 'validates_timeliness', '~> 3.0'
gem "pundit" # verify role
# admin
gem 'activeadmin', github: 'activeadmin'
gem 'kaminari', '0.16.3'
# cron job
gem 'whenever', :require => false
# upload source
gem 'capistrano', '~> 3.1.0'
gem 'capistrano-bundler', '~> 1.1.2'
gem 'capistrano-rails', '~> 1.1.1'
......
GIT
remote: git://github.com/activeadmin/activeadmin.git
revision: 5a2b7b5bc683ae98a114958c3d1eb9c932234c56
specs:
activeadmin (1.0.0.pre1)
arbre (~> 1.0, >= 1.0.2)
bourbon
coffee-rails
formtastic (~> 3.1)
formtastic_i18n
inherited_resources (~> 1.6)
jquery-rails
jquery-ui-rails (~> 5.0)
kaminari (~> 0.15)
rails (>= 3.2, < 5.0)
ransack (~> 1.3)
sass-rails
GIT
remote: git://github.com/capistrano/rvm.git
revision: 9cfef39cf0022839dca6b5b330dfefeb5fc363e7
specs:
......@@ -45,6 +63,8 @@ GEM
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.3.8)
arbre (1.0.3)
activesupport (>= 3.0.0)
arel (6.0.2)
autoprefixer-rails (5.2.1)
execjs
......@@ -57,6 +77,9 @@ GEM
sass (>= 3.2.19)
bootstrap3-datetimepicker-rails (4.7.14)
momentjs-rails (>= 2.8.1)
bourbon (4.2.3)
sass (~> 3.4)
thor
breadcrumbs_on_rails (2.3.0)
builder (3.2.2)
byebug (5.0.0)
......@@ -79,6 +102,7 @@ GEM
xpath (~> 2.0)
childprocess (0.5.6)
ffi (~> 1.0, >= 1.0.11)
chronic (0.10.2)
coderay (1.1.0)
coffee-rails (4.1.0)
coffee-script (>= 2.2.0)
......@@ -128,11 +152,22 @@ GEM
thor (~> 0.14)
font-awesome-sass (4.3.2.1)
sass (~> 3.2)
formtastic (3.1.3)
actionpack (>= 3.2.13)
formtastic_i18n (0.4.1)
gherkin (2.12.2)
multi_json (~> 1.3)
globalid (0.3.5)
activesupport (>= 4.1.0)
has_scope (0.6.0)
actionpack (>= 3.2, < 5)
activesupport (>= 3.2, < 5)
i18n (0.7.0)
inherited_resources (1.6.0)
actionpack (>= 3.2, < 5)
has_scope (~> 0.6.0.rc)
railties (>= 3.2, < 5)
responders
jbuilder (2.3.1)
activesupport (>= 3.0.0, < 5)
multi_json (~> 1.2)
......@@ -142,7 +177,12 @@ GEM
rails-dom-testing (~> 1.0)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
json (1.8.3)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
launchy (2.4.3)
addressable (~> 2.3)
loofah (2.0.2)
......@@ -164,6 +204,8 @@ GEM
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
orm_adapter (0.5.0)
polyamorous (1.2.0)
activerecord (>= 3.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
......@@ -200,6 +242,12 @@ GEM
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (10.4.2)
ransack (1.6.6)
actionpack (>= 3.0)
activerecord (>= 3.0)
activesupport (>= 3.0)
i18n
polyamorous (~> 1.2)
rdoc (4.2.0)
request_store (1.1.0)
responders (2.1.0)
......@@ -291,6 +339,8 @@ GEM
railties (>= 4.0)
sprockets-rails (>= 2.0, < 4.0)
websocket (1.2.2)
whenever (0.9.4)
chronic (>= 0.6.3)
will_paginate (3.0.7)
xpath (2.0.0)
nokogiri (~> 1.3)
......@@ -299,6 +349,7 @@ PLATFORMS
ruby
DEPENDENCIES
activeadmin!
bootstrap-sass (= 3.3.4.1)
bootstrap3-datetimepicker-rails (~> 4.7.14)
breadcrumbs_on_rails
......@@ -320,6 +371,7 @@ DEPENDENCIES
font-awesome-sass (= 4.3.2.1)
jbuilder (~> 2.0)
jquery-rails
kaminari (= 0.16.3)
momentjs-rails (>= 2.8.1)
mysql2
pry
......@@ -346,4 +398,5 @@ DEPENDENCIES
vacuum
validates_timeliness (~> 3.0)
web-console (~> 2.0)
whenever
will_paginate (~> 3.0.6)
ActiveAdmin.register_page "Dashboard" do
menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") }
content title: proc{ I18n.t("active_admin.dashboard") } do
div class: "blank_slate_container", id: "dashboard_default_message" do
span class: "blank_slate" do
span I18n.t("active_admin.dashboard_welcome.welcome")
small I18n.t("active_admin.dashboard_welcome.call_to_action")
end
end
# Here is an example of a simple dashboard with columns and panels.
#
# columns do
# column do
# panel "Recent Posts" do
# ul do
# Post.recent(5).map do |post|
# li link_to(post.title, admin_post_path(post))
# end
# end
# end
# end
# column do
# panel "Info" do
# para "Welcome to ActiveAdmin."
# end
# end
# end
end # content
end
ActiveAdmin.register Order do
actions :index, :edit, :update
permit_params :state
filter :item_total
filter :state, as: :select, collection: proc{ Order.states.map{ |k,v| [k, v] } }
filter :created_at
form do |f|
f.inputs do
f.input :pid, input_html: { disabled: true }
f.input :item_count, input_html: { disabled: true }
f.input :item_total, input_html: { disabled: true }
f.input :state, :as => :select, :collection => Order.states.map{ |k,v| k }
f.input :user_id, input_html: { disabled: true }
end
f.actions
end
end
//= require active_admin/base
// SASS variable overrides must be declared before loading up Active Admin's styles.
//
// To view the variables that Active Admin provides, take a look at
// `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the
// Active Admin source.
//
// For example, to change the sidebar width:
// $sidebar-width: 242px;
// Active Admin's got SASS!
@import "active_admin/mixins";
@import "active_admin/base";
@import "active_admin_decorator/*"
// Overriding any non-variable SASS must be done after the fact.
// For example, to change the default status-tag color:
//
// .status_tag { background: #6090DB; }
table{
td{
text-transform: capitalize;
}
}
select{
text-transform: capitalize;
}
.boolean.input{
input{
position: relative;
top:2px;
}
}
@media (max-width: 767px) {
.xs-mar-top-10{
margin-top:10px!important;
}
}
\ No newline at end of file
......@@ -24,6 +24,13 @@ class ApplicationController < ActionController::Base
end
end
def authenticate_admin_user!
authenticate_user!
unless current_user.admin?
redirect_to root_path, error: "This area is restricted to administrators only."
end
end
private
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up).push(:name)
......
......@@ -20,7 +20,6 @@ class HomeController < ApplicationController
render layout: "cart"
end
private
def get_recommend
@recommend_products = Product.recommend
......
......@@ -2,6 +2,10 @@ class OrdersController < ApplicationController
before_action :authenticate_user!
layout "cart"
def index
@orders = current_user.orders.paginate(page: params[:page])
end
def update
current_order.update_attributes(update_order_params)
redirect_to cart_path(), notice: "Update cart successfully"
......
class OrderDecorator < Draper::Decorator
include Draper::LazyHelpers
def pid_link
unless !object.cart?
h.content_tag( :i, "Order not checkout" )
else
h.content_tag( :a, object.pid, href: order_path(object.id) )
end
end
end
\ No newline at end of file
class Order < ActiveRecord::Base
enum state: [:cart, :checkout]
enum state: [:cart, :checkout, :shipping, :completed, :refund]
has_many :line_items, dependent: :destroy
belongs_to :user
......
......@@ -8,4 +8,6 @@ class User < ActiveRecord::Base
has_many :orders, dependent: :destroy
validates :name, presence: true
enum role: [:client, :admin]
end
class CronjobService
def self.update_product_price
::Product.find_each do |product|
aws_product = VacuumAwsService.item_lookup(item_id: product.pid)
product.update_columns(price: aws_product[:price]) if aws_product.present?
end
end
end
class VacuumAwsService
# search item by pid
def self.item_lookup(options={})
options[:country_code] ||='GB'
request = Vacuum.new(options[:country_code])
request.configure(
aws_access_key_id: ENV['aws_access_key_id'],
aws_secret_access_key: ENV['aws_secret_access_key'],
associate_tag: ENV['associate_tag']
)
response = request.item_lookup(
query: {
'ItemId' => options[:item_id],
'ResponseGroup' => 'Medium'
}
).to_h
if response["ItemLookupResponse"]["Items"]["Item"].present?
VacuumAwsService.parse_item(response["ItemLookupResponse"]["Items"]["Item"])
else
nil
end
end
# search items
def self.item_search(options={})
options[:country_code] ||='GB'
options[:query] ||={}
......@@ -46,7 +71,11 @@ class VacuumAwsService
end
end
# Sample item response
# Sample item lookup response ========================================================
# {"ItemLookupResponse"=>{"OperationRequest"=>{"HTTPHeaders"=>{"Header"=>{"Name"=>"UserAgent", "Value"=>"Jeff/1.3.0 (Language=Ruby; ventura-20150422)"}}, "RequestId"=>"4859b588-5fa3-4968-a8be-c4d6502cb144", "Arguments"=>{"Argument"=>[{"Name"=>"AWSAccessKeyId", "Value"=>"AKIAJ77C4CTZOP7TUVWQ"}, {"Name"=>"AssociateTag", "Value"=>"zigexn6400-22"}, {"Name"=>"ItemId", "Value"=>"0008138303"}, {"Name"=>"Operation", "Value"=>"ItemLookup"}, {"Name"=>"Service", "Value"=>"AWSECommerceService"}, {"Name"=>"SignatureMethod", "Value"=>"HmacSHA256"}, {"Name"=>"SignatureVersion", "Value"=>"2"}, {"Name"=>"Timestamp", "Value"=>"2015-07-22T07:01:16Z"}, {"Name"=>"Version", "Value"=>"2013-08-01"}, {"Name"=>"Signature", "Value"=>"jyLbyNcBVA0j+63ljixF/67d5T86nNv/UWvg+tDUqh8="}]}, "RequestProcessingTime"=>"0.0092180000000000"}, "Items"=>{"Request"=>{"IsValid"=>"True", "ItemLookupRequest"=>{"IdType"=>"ASIN", "ItemId"=>"0008138303", "ResponseGroup"=>"Small", "VariationPage"=>"All"}}, "Item"=>{"ASIN"=>"0008138303", "DetailPageURL"=>"http://www.amazon.co.uk/All-Light-We-Cannot-See/dp/0008138303%3FSubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D0008138303", "ItemLinks"=>{"ItemLink"=>[{"Description"=>"Add To Wishlist", "URL"=>"http://www.amazon.co.uk/gp/registry/wishlist/add-item.html%3Fasin.0%3D0008138303%26SubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3D0008138303"}, {"Description"=>"Tell A Friend", "URL"=>"http://www.amazon.co.uk/gp/pdp/taf/0008138303%3FSubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3D0008138303"}, {"Description"=>"All Customer Reviews", "URL"=>"http://www.amazon.co.uk/review/product/0008138303%3FSubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3D0008138303"}, {"Description"=>"All Offers", "URL"=>"http://www.amazon.co.uk/gp/offer-listing/0008138303%3FSubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D12734%26creativeASIN%3D0008138303"}]}, "ItemAttributes"=>{"Author"=>"Anthony Doerr", "Manufacturer"=>"Fourth Estate", "ProductGroup"=>"Book", "Title"=>"All the Light We Cannot See"}}}}}
# Sample item search response ========================================================
# {"ASIN"=>"B00000G43U", "DetailPageURL"=>"http://www.amazon.co.uk/All-Saints-Remix-Album-Saints/dp/B00000G43U%3FSubscriptionId%3DAKIAJ77C4CTZOP7TUVWQ%26tag%3Dzigexn6400-22%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3DB00000G43U",
# "ItemLinks"=>{
# "ItemLink"=>[
......
......@@ -28,7 +28,9 @@
tr
td= i.index+1
td= i.object.product.title
td= i.number_field :quantity, class: "form-control item-quantity", min: 1
td
= i.number_field :quantity, class: "form-control item-quantity", min: 1
span= "(available: #{i.object.product.stock})"
td
span.item-price= i.object.price
span= i.object.product.currency
......
- if policy(:product).new?
li
= link_to "New product", new_product_path
li= link_to "New product", new_product_path
- if current_user.present?
li= link_to "My orders", orders_path
- index = order_counter + 1
tr
td= index
td= order.decorate.pid_link
td= order.item_count
td= order.item_total
td= order.state
\ No newline at end of file
#orders
- if @orders.present?
.table-responsive
table.table
thead
tr
th #
th Pid
th Item count
th Item total
th State
tbody
= render @orders
.text-center
= will_paginate @products
- else
.text-center Your have no order yet
script(type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-55af38b64560cb34" async="async")
#product
h4= @product.title
= image_tag @product.image.thumb("110x86#").url
......@@ -14,5 +16,6 @@
.form-group
= number_field_tag :quantity, 1, class: "form-control"
= hidden_field_tag :product_id, @product.id
= submit_tag "Add to cart", class: "btn btn-primary"
= submit_tag "Add to cart", class: "btn btn-primary xs-mar-top-10"
.mar-top-20
.addthis_native_toolbox
\ No newline at end of file
#search-bar
= form_tag search_path, class: "form-horizontal", method: "GET" do |f|
.row
.col-sm-10
.col-sm-10.col-xs-8
= text_field_tag :keyword, params[:keyword], placeholder: "Keyword", class: "form-control"
.col-sm-2
.col-sm-2.col-xs-4
= submit_tag "Search", class: "btn btn-primary"
ActiveAdmin.setup do |config|
# == Site Title
#
# Set the title that is displayed on the main layout
# for each of the active admin pages.
#
config.site_title = "Venshop"
# Set the link url for the title. For example, to take
# users to your main site. Defaults to no link.
#
# config.site_title_link = "/"
# Set an optional image to be displayed for the header
# instead of a string (overrides :site_title)
#
# Note: Aim for an image that's 21px high so it fits in the header.
#
# config.site_title_image = "logo.png"
# == Default Namespace
#
# Set the default namespace each administration resource
# will be added to.
#
# eg:
# config.default_namespace = :hello_world
#
# This will create resources in the HelloWorld module and
# will namespace routes to /hello_world/*
#
# To set no namespace by default, use:
# config.default_namespace = false
#
# Default:
# config.default_namespace = :admin
#
# You can customize the settings for each namespace by using
# a namespace block. For example, to change the site title
# within a namespace:
#
# config.namespace :admin do |admin|
# admin.site_title = "Custom Admin Title"
# end
#
# This will ONLY change the title for the admin section. Other
# namespaces will continue to use the main "site_title" configuration.
# == User Authentication
#
# Active Admin will automatically call an authentication
# method in a before filter of all controller actions to
# ensure that there is a currently logged in admin user.
#
# This setting changes the method which Active Admin calls
# within the application controller.
config.authentication_method = :authenticate_admin_user!
# == User Authorization
#
# Active Admin will automatically call an authorization
# method in a before filter of all controller actions to
# ensure that there is a user with proper rights. You can use
# CanCanAdapter or make your own. Please refer to documentation.
# config.authorization_adapter = ActiveAdmin::CanCanAdapter
# In case you prefer Pundit over other solutions you can here pass
# the name of default policy class. This policy will be used in every
# case when Pundit is unable to find suitable policy.
# config.pundit_default_policy = "MyDefaultPunditPolicy"
# You can customize your CanCan Ability class name here.
# config.cancan_ability_class = "Ability"
# You can specify a method to be called on unauthorized access.
# This is necessary in order to prevent a redirect loop which happens
# because, by default, user gets redirected to Dashboard. If user
# doesn't have access to Dashboard, he'll end up in a redirect loop.
# Method provided here should be defined in application_controller.rb.
# config.on_unauthorized_access = :access_denied
# == Current User
#
# Active Admin will associate actions with the current
# user performing them.
#
# This setting changes the method which Active Admin calls
# (within the application controller) to return the currently logged in user.
# config.current_user_method = :current_admin_user
# == Logging Out
#
# Active Admin displays a logout link on each screen. These
# settings configure the location and method used for the link.
#
# This setting changes the path where the link points to. If it's
# a string, the strings is used as the path. If it's a Symbol, we
# will call the method to return the path.
#
# Default:
config.logout_link_path = :destroy_admin_user_session_path
# This setting changes the http method used when rendering the
# link. For example :get, :delete, :put, etc..
#
# Default:
# config.logout_link_method = :get
# == Root
#
# Set the action to call for the root path. You can set different
# roots for each namespace.
#
# Default:
# config.root_to = 'dashboard#index'
# == Admin Comments
#
# This allows your users to comment on any resource registered with Active Admin.
#
# You can completely disable comments:
# config.comments = false
#
# You can disable the menu item for the comments index page:
# config.show_comments_in_menu = false
#
# You can change the name under which comments are registered:
# config.comments_registration_name = 'AdminComment'
# == Batch Actions
#
# Enable and disable Batch Actions
#
config.batch_actions = true
# == Controller Filters
#
# You can add before, after and around filters to all of your
# Active Admin resources and pages from here.
#
# config.before_filter :do_something_awesome
# == Setting a Favicon
#
# config.favicon = 'favicon.ico'
# == Removing Breadcrumbs
#
# Breadcrumbs are enabled by default. You can customize them for individual
# resources or you can disable them globally from here.
#
# config.breadcrumb = false
# == Register Stylesheets & Javascripts
#
# We recommend using the built in Active Admin layout and loading
# up your own stylesheets / javascripts to customize the look
# and feel.
#
# To load a stylesheet:
# config.register_stylesheet 'my_stylesheet.css'
#
# You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
# config.register_stylesheet 'my_print_stylesheet.css', media: :print
#
# To load a javascript file:
# config.register_javascript 'my_javascript.js'
# == CSV options
#
# Set the CSV builder separator
# config.csv_options = { col_sep: ';' }
#
# Force the use of quotes
# config.csv_options = { force_quotes: true }
# == Menu System
#
# You can add a navigation menu to be used in your application, or configure a provided menu
#
# To change the default utility navigation to show a link to your website & a logout btn
#
# config.namespace :admin do |admin|
# admin.build_menu :utility_navigation do |menu|
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
# admin.add_logout_button_to_menu menu
# end
# end
#
# If you wanted to add a static menu item to the default menu provided:
#
# config.namespace :admin do |admin|
# admin.build_menu :default do |menu|
# menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
# end
# end
# == Download Links
#
# You can disable download links on resource listing pages,
# or customize the formats shown per namespace/globally
#
# To disable/customize for the :admin namespace:
#
# config.namespace :admin do |admin|
#
# # Disable the links entirely
# admin.download_links = false
#
# # Only show XML & PDF options
# admin.download_links = [:xml, :pdf]
#
# # Enable/disable the links based on block
# # (for example, with cancan)
# admin.download_links = proc { can?(:view_download_links) }
#
# end
# == Pagination
#
# Pagination is enabled by default for all resources.
# You can control the default per page count for all resources here.
#
# config.default_per_page = 30
# == Filters
#
# By default the index screen includes a "Filters" sidebar on the right
# hand side with a filter for each attribute of the registered model.
# You can enable or disable them for all resources here.
#
# config.filters = true
end
Kaminari.configure do |config|
config.page_method_name = :per_page_kaminari # config for prevent conflig with will_paginate in client
end
\ No newline at end of file
Rails.application.routes.draw do
devise_for :users
ActiveAdmin.routes(self)
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
......@@ -10,7 +11,7 @@ Rails.application.routes.draw do
resources :categories, :only => [:show]
resources :products, :only => [:new, :create, :show]
resources :orders, :only => [:update, :show] do
resources :orders, :only => [:index, :update, :show] do
collection do
get "checkout" => "orders#checkout", as: :checkout
post "add_to_cart" => "orders#add_to_cart", as: :add_to_cart
......
# Use this file to easily define all of your cron jobs.
#
# It's helpful, but not entirely necessary to understand cron before proceeding.
# http://en.wikipedia.org/wiki/Cron
# Example:
#
set :output, 'log/cron.log'
set :environment, "development"
every 1.hours do
runner "CronjobService.update_product_price"
end
# every 4.days do
# runner "AnotherModel.prune_old_records"
# end
# Learn more: http://github.com/javan/whenever
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer, default: 0
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150717065015) do
ActiveRecord::Schema.define(version: 20150722043822) do
create_table "categories", force: :cascade do |t|
t.string "name", limit: 255
......@@ -66,6 +66,7 @@ ActiveRecord::Schema.define(version: 20150717065015) do
t.datetime "created_at"
t.datetime "updated_at"
t.string "name", limit: 255
t.integer "role", limit: 4, default: 0
end
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
......
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