diff --git a/plugins/shopping_cart/public/cart.js b/plugins/shopping_cart/public/cart.js
new file mode 100644
index 0000000..d24c79c
--- /dev/null
+++ b/plugins/shopping_cart/public/cart.js
@@ -0,0 +1,246 @@
+function Cart(config) {
+ var $ = jQuery;
+ Cart.instance = this; // this may be a list on the future;
+ this.cartElem = $("#cart1")[0];
+ this.cartElem.cartObj = this;
+ this.contentBox = $("#cart1 .cart-content");
+ this.itemsBox = $("#cart1 .cart-items");
+ this.items = {};
+ this.visible = false;
+ if (config.hasProducts) {
+ $(this.cartElem).show();
+ this.enterprise = config.enterprise;
+ this.listProducts();
+ }
+ $(".cart-buy", this.cartElem).button({ icons: { primary: 'ui-icon-cart'} });
+}
+
+(function($){
+
+ Cart.prototype.listProducts = function() {
+ var me = this;
+ $.ajax({
+ url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/list',
+ dataType: 'json',
+ success: function(data, ststus, ajax){
+ if ( !data.ok ) alert(data.error.message);
+ else me.addToList(data, true);
+ },
+ cache: false,
+ error: function(ajax, status, errorThrown) {
+ alert('List cart items - HTTP '+status+': '+errorThrown);
+ }
+ });
+ }
+
+ Cart.prototype.addToList = function(data, clear) {
+ if( clear ) this.itemsBox.empty();
+ var me = this;
+ for( var item,i=0; item=data.products[i]; i++ ) {
+ this.items[item.id] = { price:item.price, quantity:item.quantity };
+ this.updateTotal();
+ var liId = "cart-item-"+item.id;
+ var li = $("#"+liId);
+ if( !li[0] ) li = $('
\n').appendTo(this.itemsBox);
+ li.empty();
+ $('' +
+ ''+ item.name +'' +
+ '' +
+ ''+ (item.price ? '× '+ item.price : '') +'
' +
+ ' remove'
+ ).appendTo(li);
+ var input = $("input", li)[0];
+ input.lastValue = input.value;
+ input.itemId = item.id;
+ input.ajustSize = function() {
+ var len = this.value.toString().length;
+ if(len > 2) len--;
+ this.style.width = len+"em";
+ };
+ input.ajustSize();
+ input.onchange = function() {
+ me.updateQuantity(this, this.itemId, this.value);
+ };
+ document.location.href = "#"+liId;
+ document.location.href = "#"+this.cartElem.id;
+ history.go(-2);
+ var liBg = li.css("background-color");
+ li[0].style.backgroundColor = "#FF0";
+ li.animate({ backgroundColor: liBg }, 1000);
+ }
+ if( !this.visible ) {
+ this.contentBox.hide();
+ this.show();
+ }
+ }
+
+ Cart.prototype.updateQuantity = function(input, itemId, quantity) {
+ quantity = parseInt(quantity);
+ input.disabled = true;
+ var originalBg = input.style.backgroundImage;
+ input.style.backgroundImage = "url(/images/loading-small.gif)";
+ var me = this;
+ if( quantity == NaN ) return input.value = input.lastValue;
+ $.ajax({
+ url: '/profile/'+ this.enterprise +'/plugins/shopping_cart/update_quantity/'+ itemId +'?quantity='+ quantity,
+ dataType: 'json',
+ success: function(data, status, ajax){
+ if ( !data.ok ) {
+ alert(data.error.message);
+ input.value = input.lastValue;
+ }
+ else {
+ input.lastValue = quantity;
+ me.items[itemId].quantity = quantity;
+ me.updateTotal();
+ }
+ },
+ cache: false,
+ error: function(ajax, status, errorThrown) {
+ alert('Add item - HTTP '+status+': '+errorThrown);
+ input.value = input.lastValue;
+ },
+ complete: function(){
+ input.disabled = false;
+ input.style.backgroundImage = originalBg;
+ input.ajustSize();
+ }
+ });
+ }
+
+ Cart.prototype.removeFromList = function(itemId) {
+ $("#cart-item-"+itemId).slideUp(500, function() {$(this).remove()});
+ delete this.items[itemId];
+ this.updateTotal();
+ }
+
+ Cart.addItem = function(enterprise, itemId, link) {
+ // on the future, the instance may be found by the enterprise identifier.
+ link.intervalId = setInterval(function() {
+ steps = ['w', 'n', 'e', 's'];
+ if( !link.step || link.step==3 ) link.step = 0;
+ link.step++;
+ $(link).button({ icons: { primary: 'ui-icon-arrowrefresh-1-'+steps[link.step]}, disable: true })
+ }, 100);
+ var stopBtLoading = function() {
+ clearInterval(link.intervalId);
+ $(link).button({ icons: { primary: 'ui-icon-cart'}, disable: false });
+ };
+ this.instance.addItem(enterprise, itemId, stopBtLoading);
+ }
+
+ Cart.prototype.addItem = function(enterprise, itemId, callback) {
+ if(!this.enterprise) {
+ this.enterprise = enterprise;
+ if( !this.visible ) $(this.cartElem).show();
+ }
+ var me = this;
+ $.ajax({
+ url: '/profile/'+ enterprise +'/plugins/shopping_cart/add/'+ itemId,
+ dataType: 'json',
+ success: function(data, status, ajax){
+ if ( !data.ok ) alert(data.error.message);
+ else me.addToList(data);
+ },
+ cache: false,
+ error: function(ajax, status, errorThrown) {
+ alert('Add item - HTTP '+status+': '+errorThrown);
+ },
+ complete: callback
+ });
+ }
+
+ Cart.removeItem = function(enterprise, itemId) {
+ var message = this.instance.cartElem.getAttribute('data-l10nRemoveItem');
+ if( confirm(message) ) this.instance.removeItem(enterprise, itemId);
+ }
+
+ Cart.prototype.removeItem = function(enterprise, itemId) {
+ if ($("li", this.itemsBox).size() < 2) return this.clean();
+ var me = this;
+ $.ajax({
+ url: '/profile/'+ enterprise +'/plugins/shopping_cart/remove/'+ itemId,
+ dataType: 'json',
+ success: function(data, status, ajax){
+ if ( !data.ok ) alert(data.error.message);
+ else me.removeFromList(data.product_id);
+ },
+ cache: false,
+ error: function(ajax, status, errorThrown) {
+ alert('Remove item - HTTP '+status+': '+errorThrown);
+ }
+ });
+ }
+
+ Cart.toggle = function(link) {
+ link.parentNode.parentNode.cartObj.toggle();
+ }
+ Cart.prototype.toggle = function() {
+ this.visible ? this.hide() : this.show();
+ }
+
+ Cart.prototype.show = function() {
+ this.visible = true;
+ this.contentBox.slideDown(500);
+ $(".cart-toggle .str-show", this.cartElem).hide();
+ $(".cart-toggle .str-hide", this.cartElem).show();
+
+ }
+ Cart.prototype.hide = function() {
+ this.visible = false;
+ this.contentBox.slideUp(500);
+ $(".cart-toggle .str-show", this.cartElem).show();
+ $(".cart-toggle .str-hide", this.cartElem).hide();
+ }
+
+ Cart.prototype.updateTotal = function() {
+ var total = 0;
+ var currency, sep = "";
+ for( var itemId in this.items ) {
+ var item = this.items[itemId];
+ if( item.price ) {
+ currency = item.price.replace(/^([^0-9]+).*$/, "$1");
+ sep = item.price.charAt(item.price.length-3);
+ var price = item.price.replace(/[^0-9]/g,"");
+ total += item.quantity * parseFloat(price);
+ }
+ }
+ total = Math.round(total).toString().replace(/(..)$/, sep+"$1")
+ $(".cart-total b", this.cartElem).text( ( (total!=0) ? currency+" "+total : "---" ) );
+ }
+
+ Cart.clean = function(link) {
+ var message = this.instance.cartElem.getAttribute('data-l10nCleanCart');
+ if( confirm(message) ) link.parentNode.parentNode.parentNode.cartObj.clean();
+ }
+
+ Cart.prototype.clean = function() {
+ var me = this;
+ $.ajax({
+ url: '/profile/'+ me.enterprise +'/plugins/shopping_cart/clean',
+ dataType: 'json',
+ success: function(data, status, ajax){
+ if ( !data.ok ) alert(data.error.message);
+ else{
+ me.items = {};
+ $(me.cartElem).slideUp(500, function() {
+ $(me.itemsBox).empty();
+ me.hide();
+ me.enterprise = null;
+ me.updateTotal();
+ });
+ }
+ },
+ cache: false,
+ error: function(ajax, status, errorThrown) {
+ alert('Remove item - HTTP '+status+': '+errorThrown);
+ }
+ });
+ }
+
+ $(function(){
+ $('.cart-add-item').button({ icons: { primary: 'ui-icon-cart'} })
+ });
+
+})(jQuery);
diff --git a/plugins/shopping_cart/public/style.css b/plugins/shopping_cart/public/style.css
new file mode 100644
index 0000000..d9e3b32
--- /dev/null
+++ b/plugins/shopping_cart/public/style.css
@@ -0,0 +1,106 @@
+.cart-add-item {
+ position: absolute;
+ right: 5px;
+ top: 5px;
+}
+
+.cart {
+ position: absolute;
+ right: 20px;
+ top: 0px;
+ width: 200px;
+ z-index: 1000;
+ border: 1px solid #777;
+ border-top: none;
+ background: rgba(200,200,200,0.6);
+}
+
+.cart h3 {
+ color: #888;
+ margin: 0px 0px 0px 5px;
+}
+
+.cart-clean {
+ color: #AAA;
+ position: absolute;
+ top: 1px;
+ right: 5px;
+ text-decoration: none;
+}
+.cart-clean:hover {
+ color: #888;
+}
+
+.cart-content {
+ display: none;
+}
+
+.cart-items {
+ margin: 0px;
+ padding: 0px;
+ max-height: 328px;
+ overflow: auto;
+}
+
+.cart-items li {
+ height: 50px;
+ padding: 5px;
+ margin: 3px;
+ border: 1px solid #999;
+ list-style: none;
+ background: #FFF;
+ position: relative;
+}
+
+.cart-items .picture {
+ float: left;
+ width: 50px;
+ height: 50px;
+ margin-right: 10px;
+ background-repeat: no-repeat;
+ background-position: 50% 50%;
+}
+
+.cart .item-name {
+ margin-right: 20px;
+}
+
+.cart .button {
+ position: absolute;
+ top: 2px;
+ right: 2px;
+}
+
+.cart input {
+ border: 1px solid transparent;
+ background: transparent 50% 50% no-repeat;
+ text-align: center;
+ padding: 0px;
+ font-family: monospace;
+ width: 2em;
+}
+.cart:hover input, .cart input:focus {
+ border: 1px solid #CCC;
+}
+
+.cart-buy {
+ display: block;
+ margin: 2px 4px;
+}
+
+.cart-total {
+ position: absolute;
+ left: 5px;
+ bottom: 0px;
+}
+
+.cart-toggle {
+ display: block;
+ color: #AAA;
+ text-decoration: none;
+ float: right;
+ padding: 0px 5px;
+}
+.cart-toggle:hover {
+ color: #555;
+}
diff --git a/plugins/shopping_cart/views/cart.html.erb b/plugins/shopping_cart/views/cart.html.erb
new file mode 100644
index 0000000..a351768
--- /dev/null
+++ b/plugins/shopping_cart/views/cart.html.erb
@@ -0,0 +1,21 @@
+
+
+
--
libgit2 0.21.2