Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Top banner #42

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
SpreeDigitalAssets
==================
Try Spree Top banner feature:

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/vinsol-spree-contrib/spree-demo-heroku/tree/spree-top-banner)

This gem allows you to have a central repository of the assets. The assets can be uploaded well
in advance and can be associated with the products/variants at the time of product/variant
Expand All @@ -23,6 +26,7 @@ Try Spree Digital Assets for Spree 3-1 with direct deployment on Heroku:

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/vinsol-spree-contrib/spree-demo-heroku/tree/spree-digital-assets-3-1)

**Note** Add gem 'bootstrap-toggle-rails' to gemfile.

## Features

Expand Down Expand Up @@ -56,6 +60,12 @@ For more features or usage manual go [here](http://vinsol.com/spreecommerce-digi
gem 'spree_digital_assets', github: 'vinsol-spree-contrib/spree_digital_assets', branch: 'X-X-stable'
```

Also Add To your gemfile

```ruby
gem 'browser', '2.0.3'
```

The `branch` option is important: it must match the version of Spree you're using.
For example, use `3-0-stable` if you're using Spree `3-0-stable` or any `3.0.x` version.

Expand Down
8 changes: 8 additions & 0 deletions app/assets/javascripts/spree/backend/bootstrap_toggle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
//= require spree/backend/spree_digital_assets/upload-assets
//= require spree/backend/spree_digital_assets/folder
//= require spree/backend/spree_digital_assets/asset_details

Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ AssetDetails.prototype.setAttributes = function($assetDetailsArea, $img) {
$assetDetailsArea.find('#created-date').html($img.data('created-on'));
$assetDetailsArea.find('#modified-date').html($img.data('modified-on'));
$assetDetailsArea.find('#related-products').html(this.setRelatedProducts($assetDetailsArea, $img.data('related-products')));
$assetDetailsArea.find('#image-url').html($img.data('image-url'));

};

AssetDetails.prototype.setRelatedProducts = function($assetDetailsArea, data) {
var $relatedProducts = $assetDetailsArea.find('#related-products').html('');
if(!data.length) {
$relatedProducts.html('None');
}
}
$.each(data, function(index, product) {
$relatedProducts.append($('<a>').attr('href', '/admin/products/' + product.slug + '/edit')
.text(product.name).css('display', 'block'));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
function BannerToggler(options){
this.$toggleSwitches = options.$toggleSwitches;
}

BannerToggler.prototype.init = function(){
this.$toggleSwitches.on('change', this.sendAjaxToUpdateActivate());
};

BannerToggler.prototype.sendAjaxToUpdateActivate = function(){
var _this = this;

return function(){
$.ajax({
url: _this.getToggleUrl(this),
type: "PATCH",
context: this,
dataype: "json"
})
.done(_this.toggleEnabled)
.fail(function(xhr, status, errorThrown){
show_flash('error', xhr.responseJSON.error);
});
};

};

BannerToggler.prototype.toggleEnabled = function(response){
$(this).data("active", response.active);
};

BannerToggler.prototype.getToggleUrl = function(element){
if($(element).data('active')){
return "/admin/banners/:id/deactivate".replace(":id", $(element).data('banner-id'))
}
else{
return "/admin/banners/:id/activate".replace(":id", $(element).data('banner-id'))
}
};

$(function(){

var bannerTogglerArguments = { $toggleSwitches : $("[data-toggle-switch='yes']") },
bannerToggler = new BannerToggler(bannerTogglerArguments);

bannerToggler.init();
});
28 changes: 28 additions & 0 deletions app/assets/stylesheets/spree/backend/bootstrap_toggle.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px}
.toggle{position:relative;overflow:hidden}
.toggle input[type=checkbox]{display:none}
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
.toggle.off .toggle-group{left:-100%}
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
.toggle.btn{min-width:59px;min-height:34px}
.toggle-on.btn{padding-right:24px}
.toggle-off.btn{padding-left:24px}
.toggle.btn-lg{min-width:79px;min-height:45px}
.toggle-on.btn-lg{padding-right:31px}
.toggle-off.btn-lg{padding-left:31px}
.toggle-handle.btn-lg{width:40px}
.toggle.btn-sm{min-width:50px;min-height:30px}
.toggle-on.btn-sm{padding-right:20px}
.toggle-off.btn-sm{padding-left:20px}
.toggle.btn-xs{min-width:35px;min-height:22px}
.toggle-on.btn-xs{padding-right:12px}
.toggle-off.btn-xs{padding-left:12px}
4 changes: 4 additions & 0 deletions app/assets/stylesheets/spree/backend/spree_digital_assets.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ Placeholder manifest file.
the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
*= require spree/backend/spree_digital_assets/style
*/

.note {
font-size: 10px;
}
11 changes: 11 additions & 0 deletions app/assets/stylesheets/spree/frontend/spree_digital_assets.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,14 @@
Placeholder manifest file.
the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
*/
.banner-list-flex {
display: flex;
display: -webkit-flex;
justify-content: space-around;
-webkit-justify-content: space-around;
align-items: center;
-webkit-align-items: center;
}
.banner-list-flex-item {
display: block;
}
83 changes: 83 additions & 0 deletions app/controllers/spree/admin/banners_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
module Spree
module Admin
class BannersController < ResourceController

before_action :load_banner, only: [:edit, :update, :destroy, :activate, :deactivate]
before_action :load_folders, only: [:new, :create, :edit, :update]
before_action :create_banner_and_images, only: [:create]

def create
if @banner.save
flash[:success] = Spree.t(:successfully_created_banner)
redirect_to admin_banners_path
else
render :new
end
end

def index
params[:q] ||= {}
@search = Spree::Banner.order(created_at: :desc).ransack(params[:q])
@banners = @search.result(distinct: true).page(params[:page]).per(params[:per_page])
end

def activate
if @banner.activate
render json: { active: 'Yes' }, status: 200
else
render json: { error: @banner.errors.full_messages.join(', ') }, status: 422
end
end

def deactivate
if @banner.deactivate
render json: { active: 'No' }, status: 200
else
render json: { error: @banner.errors.full_messages.join(', ') }, status: 422
end
end

def toggle_banner_active_status
if @banner.change_active_status
flash[:success] = Spree.t(:successfully_updated_banner)
else
flash[:notice] = @banner.errors.full_messages.join
end
redirect_to admin_banners_path
end

def update
if @banner.update(permitted_params)
flash[:success] = Spree.t(:successfully_updated_banner)
redirect_to admin_banners_path
else
render :edit
end
end

private

def create_banner_and_images
@banner = Banner.new(permitted_params)
if permitted_resource_params[:images][:digital_asset_id].present?
@banner.images << Spree::Image.new(permitted_resource_params[:images])
end
end

def load_folders
@folders = Spree::Folder.all
@digital_assets = Spree::DigitalAsset.approved.page(params[:page])
end

def permitted_params
params.require(:banner).permit(:title, :attachment, :link, :active, :mobile_banner)
end

def load_banner
@banner = Spree::Banner.find_by(id: params[:id])
end

end
end

end
10 changes: 10 additions & 0 deletions app/controllers/spree/application_controller_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
ApplicationController.class_eval do

before_action :detect_device_variant

private

def detect_device_variant
request.variant = :phone if browser.device.mobile?
end
end
24 changes: 17 additions & 7 deletions app/helpers/spree/admin/base_helper_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,23 +51,33 @@ def delete_folder_link(folder, options)
end

def asset_details(digital_asset)
{
{
id: digital_asset.id,
name: digital_asset.name,
size: number_to_human_size(digital_asset.attachment_file_size),
created_on: digital_asset.created_at.to_date.to_formatted_s(:long),
modified_on: digital_asset.updated_at.to_date.to_formatted_s(:long),
related_products: related_products(digital_asset)
size: number_to_human_size(digital_asset.attachment_file_size),
created_on: digital_asset.created_at.to_date.to_formatted_s(:long),
modified_on: digital_asset.updated_at.to_date.to_formatted_s(:long),
related_products: related_products(digital_asset),
image_url: request.host_with_port + digital_asset.attachment.url
}
end

def related_products(digital_asset)
products = {}
digital_asset.assets.each do |asset|
product = asset.viewable.product
products[product.id] = { slug: product.slug, name: product.name }
product = asset.viewable.try(:product)
products[product.id] = { slug: product.slug, name: product.name } if product
end
products.values
end

def banner_active(banner)
if banner.active
"btn-success"
else
"btn-danger"
end
end


end
1 change: 1 addition & 0 deletions app/models/spree/backend_configuration_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Spree::BackendConfiguration::BANNER ||= [:banner]
72 changes: 72 additions & 0 deletions app/models/spree/banner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module Spree
class Banner < Spree::Base

URL_VALIDATION_REGEX = /^(http|https):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/ix

has_attached_file :attachment, styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>' },
url: '/spree/banner/:id/:style/:basename.:extension',
path: ':rails_root/public/spree/banner/:id/:style/:basename.:extension'


validates_attachment :attachment, content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }
validate :only_one_mobile_banner
has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: 'Spree::Image'

with_options presence: true do
validates :title, uniqueness: true
validates :link
validates :attachment, unless: :images_present?
validates :images, unless: :attachment?
end

validates_format_of :link, with: URL_VALIDATION_REGEX, multiline: true, allow_blank: true

validate :both_image_and_attachment_not_present

scope :active, -> { where(active: true) }
scope :mobile_active_banner, -> { where(mobile_banner: true, active: true) }

before_destroy :restrict_if_active


def deactivate
update(active: false, mobile_banner: false)
end

def activate
update(active: true)
end

private

def images_present?
images.present?
end

def only_one_mobile_banner
if mobile_banner?
if !active?
errors.add(:base, Spree.t(:only_active_mobile_banner))
elsif other_mobile_banner_active?
errors.add(:base, Spree.t(:only_one_mobile_banner))
end
end
end

def other_mobile_banner_active?
(Banner.mobile_active_banner - [self]).length > 0
end

def restrict_if_active
if active?
errors.add(:base, Spree.t(:cannot_delete_active_banner))
throw(:abort)
end
end

def both_image_and_attachment_not_present
errors.add(:base, Spree.t(:both_asset_and_attachment)) if images.present? && attachment?
end

end
end
8 changes: 8 additions & 0 deletions app/models/spree/image_decorator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Spree::Image.class_eval do
has_attached_file :attachment,
styles: { mini: '48x48>', small: '100x100>', product: '240x240>', large: '600x600>', banner: '1022x60>' },
default_style: :product,
url: '/spree/products/:id/:style/:basename.:extension',
path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
end
6 changes: 6 additions & 0 deletions app/overrides/add_banner_div_to_layout.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Deface::Override.new(
virtual_path: 'spree/shared/_header',
name: 'add_banner_div_to_layout',
insert_after: "div#spree-header > div.container",
partial: 'spree/layouts/banner_div'
)
7 changes: 7 additions & 0 deletions app/overrides/add_banner_tab.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Deface::Override.new(
virtual_path: 'spree/admin/shared/sub_menu/_configuration',
name: 'add_banner_tab',
insert_bottom: "[data-hook='admin_configurations_sidebar_menu']",
text: "<%= configurations_sidebar_menu_item Spree.t(:banner), admin_banners_path %>"

)
Loading