diff --git a/back-office/app/models/item.rb b/back-office/app/models/item.rb index 14649b1..016389e 100644 --- a/back-office/app/models/item.rb +++ b/back-office/app/models/item.rb @@ -3,7 +3,7 @@ class Item < ActiveRecord::Base has_many :multi_media_descriptions belongs_to :sub_category belongs_to :supplier - has_and_belongs_to_many :item_groups, :join_table => 'item_item_groups' + has_and_belongs_to_many :item_groups, :join_table => 'item_item_groups' validates_presence_of :name, :description, :list_price, :current_input_price, :tags, :unit_id, :code, :sub_category_id, :weight, :supplier_id diff --git a/back-office/app/models/item_group.rb b/back-office/app/models/item_group.rb index 1df6aa7..b6c50aa 100644 --- a/back-office/app/models/item_group.rb +++ b/back-office/app/models/item_group.rb @@ -1,4 +1,5 @@ class ItemGroup < ActiveRecord::Base has_and_belongs_to_many :items, :join_table => 'item_item_groups' + end diff --git a/front-api/controllers/item.rb b/front-api/controllers/item.rb index fb88f2a..d491405 100644 --- a/front-api/controllers/item.rb +++ b/front-api/controllers/item.rb @@ -73,6 +73,7 @@ get '/item/sub_category/:sub_category_id/offset/:offset/limit/:limit' do |sub_ca prepare_items_for_mass_display(items) end + # gets list of items in cart without count get '/cart/item_details' do cart = Cart.find_or_create(anonymous_id, -1) @@ -83,3 +84,14 @@ get '/cart/item_details' do items = Item.find(item_ids) if cart.item_in_carts.length > 0 prepare_items_for_mass_display(items) end + + +# gets items in sub category ( useful for page showing single sub_category ) +get '/item/item_group/:item_group_id/offset/:offset/limit/:limit' do |item_group_id_s, offset_s, limit_s| + item_group_id, offset, limit = mass_to_i(item_group_id_s, offset_s, limit_s) + input_invalid = offset_and_limit_invalid?(offset,limit) or item_group_id <= 0 + return [].to_json if input_invalid + + items = ItemGroup.find(item_group_id).all_items(offset, limit) + prepare_items_for_mass_display(items) +end \ No newline at end of file diff --git a/front-api/models/item_group.rb b/front-api/models/item_group.rb new file mode 100644 index 0000000..edc5619 --- /dev/null +++ b/front-api/models/item_group.rb @@ -0,0 +1,8 @@ +class ItemGroup < ActiveRecord::Base + has_and_belongs_to_many :items, :join_table => 'item_item_groups' + + def all_items(offset, limit) + self.items.where(on_display: true).order(:created_at).limit(limit).offset(offset).all + end + +end diff --git a/front-ui/app/actions/itemActions.js b/front-ui/app/actions/itemActions.js index d26e254..68399f4 100644 --- a/front-ui/app/actions/itemActions.js +++ b/front-ui/app/actions/itemActions.js @@ -31,6 +31,13 @@ var ItemActions = { actionType : ItemConstants.LOAD_BSI_FOR_SECTION, sectionId: sectionId }); + }, + + loadBestSellingItemsForGroup: function(groupId) { + AppDispatcher.handleAction({ + actionType : ItemConstants.LOAD_BSI_FOR_ITEM_GROUP, + groupId: groupId + }); } }; diff --git a/front-ui/app/components/items/allItemsInGroup.js b/front-ui/app/components/items/allItemsInGroup.js new file mode 100644 index 0000000..ac1f834 --- /dev/null +++ b/front-ui/app/components/items/allItemsInGroup.js @@ -0,0 +1,44 @@ +var React = require('react'); +var ItemList = require('./itemList'); +var ItemStore = require('../../stores/itemStore.js'); +var ItemActions = require('../../actions/itemActions.js'); +var ItemCollection = require('../../models/itemCollection'); +var NavigationStore = require('../../stores/navigationStore.js'); + +var AllItemsInGroup = React.createClass({ + + render: function() { + return ( + + ); + }, + + // Add change listeners to stores + componentDidMount: function() { + ItemActions.loadBestSellingItemsForGroup(NavigationStore.getGroupIdFromUrl()); + ItemStore.addChangeListener(this._onChange); + }, + + + componentWillUnmount: function () { + ItemStore.removeChangeListener(this._onChange); + }, + + + getInitialState: function() { + return { + items: ItemStore.getItemsForGroup() + } + }, + + + _onChange: function () { + if (this.isMounted()) { + this.setState({ + items: ItemStore.getItemsForGroup() + }); + } + }, +}); + +module.exports = AllItemsInGroup; diff --git a/front-ui/app/components/items/itemGroupPage.js b/front-ui/app/components/items/itemGroupPage.js new file mode 100644 index 0000000..fa26211 --- /dev/null +++ b/front-ui/app/components/items/itemGroupPage.js @@ -0,0 +1,22 @@ +var React = require('react'), + Router = require('react-router'), + RouteHandler = Router.RouteHandler, + AllItemsInGroup = require('../items/allItemsInGroup'); + +var ItemGroupPage = React.createClass({ + render : function() { + return ( +
+ +
+ +
+
+ +
+
+ ) + } +}); + +module.exports = ItemGroupPage; diff --git a/front-ui/app/constants/itemConstants.js b/front-ui/app/constants/itemConstants.js index 9d0d9a6..9490a9d 100644 --- a/front-ui/app/constants/itemConstants.js +++ b/front-ui/app/constants/itemConstants.js @@ -4,5 +4,6 @@ var keyMirror = require('react/lib/keyMirror'); module.exports = keyMirror({ LOAD_FOR_FRONTPAGE: null, LOAD_BSI_FOR_SECTION: null, + LOAD_BSI_FOR_ITEM_GROUP: null, LOAD_BY_CATEGORY: null }); diff --git a/front-ui/app/css/main.css b/front-ui/app/css/main.css index 0981f78..e0888ab 100644 --- a/front-ui/app/css/main.css +++ b/front-ui/app/css/main.css @@ -1,6 +1,6 @@ body { /*background-image: url(https://res.cloudinary.com/lfvt7ps2n/image/upload/v1424608718/http_diapers.q-assets.com_images_body_bg_towkjs.gif);*/ - background-image : url(http://www.windeln.de/resources/img/bg.svg); + background-image : url(https://res.cloudinary.com/lfvt7ps2n/image/upload/v1427091632/http_www.windeln.de_resources_img_bg_s76hro.svg); font-family: Arial, Helvetica, sans-serif; font-size: 12px; height:100%; diff --git a/front-ui/app/models/itemCollection.js b/front-ui/app/models/itemCollection.js index a103e93..c920715 100644 --- a/front-ui/app/models/itemCollection.js +++ b/front-ui/app/models/itemCollection.js @@ -31,7 +31,7 @@ var ItemCollection = Backbone.Collection.extend({ this.offset = offset; }, - classificationTypeUrlParts: ['', 'section', 'category', 'sub_category'], + classificationTypeUrlParts: ['', 'section', 'category', 'sub_category', 'item_group'], setClassificationType: function(type) { this.classificationType = type; diff --git a/front-ui/app/router.js b/front-ui/app/router.js index 452b9cc..2ea4f27 100644 --- a/front-ui/app/router.js +++ b/front-ui/app/router.js @@ -8,6 +8,7 @@ var ItemWithDetailsPage = require('./components/items/itemWithDetailsPage'); var ItemList = require('./components/items/itemList'); var SectionsListComponent = require('./components/shared/sectionsListComponent'); var AllItems = require('./components/items/allItems'); +var ItemGroupPage = require('./components/items/itemGroupPage'); var CartPage = require('./components/cart/cartPage'); var CheckoutPage = require('./components/cart/checkoutPage'); var RootApp = require('./components/rootApp'); @@ -25,6 +26,7 @@ var routes = ( + diff --git a/front-ui/app/stores/itemStore.js b/front-ui/app/stores/itemStore.js index 3b63020..1a4af6f 100644 --- a/front-ui/app/stores/itemStore.js +++ b/front-ui/app/stores/itemStore.js @@ -9,7 +9,8 @@ var _ = require('underscore'); var _items = new ItemCollection(), _itemWithDetails = new ItemWithDetails(), _bestSellingForSection = new ItemCollection(), - _itemsByCategory = new ItemCollection(); + _itemsByCategory = new ItemCollection(), + _bestSellingForGroup = new ItemCollection(); var loadItemsForFrontpage = function() { @@ -93,6 +94,22 @@ var fetchBestSellingItemsForSection = function(sectionId) { }; +var fetchBestSellingItemsForGroup = function(groupId) { + console.log('getting group', groupId); + var items = _bestSellingForGroup; + items.setClassificationType(4); + items.setClassificationId(groupId); + items.setLimit(30); + items.setOffset(0); + + items.fetch({ + success: function() { + ItemStore.emitChange(); + } + }); +}; + + // Extend ItemStore with EventEmitter to add eventing capabilities var ItemStore = _.extend({}, EventEmitter.prototype, { @@ -108,6 +125,10 @@ var ItemStore = _.extend({}, EventEmitter.prototype, { return _itemWithDetails; }, + getItemsForGroup: function () { + return _bestSellingForGroup; + }, + // Return All Items getItems: function() { @@ -148,6 +169,10 @@ AppDispatcher.register(function(payload) { fetchBestSellingItemsForSection(action.sectionId); break; + case ItemConstants.LOAD_BSI_FOR_ITEM_GROUP: + fetchBestSellingItemsForGroup(action.groupId); + break; + case ItemConstants.LOAD_FOR_FRONTPAGE: loadItemsForFrontpage(); break; diff --git a/front-ui/app/stores/navigationStore.js b/front-ui/app/stores/navigationStore.js index ddee1f9..6b2b22e 100644 --- a/front-ui/app/stores/navigationStore.js +++ b/front-ui/app/stores/navigationStore.js @@ -5,10 +5,24 @@ var NavigationConstants = require('../constants/navigationConstants') var _ = require('underscore'); + + +var getGroupIdFromUrl = function() { + console.log("yeee" , match); + // ugly but it seems to me that + // router does not want to expose its + // state (for phylosophical reasons) + var url = document.URL; + var itemIdRegex = /grupa\/(\d+)\//g; + var match = itemIdRegex.exec(url); + console.log(match); + return match[1]; +}; + // Extend ItemStore with EventEmitter to add eventing capabilities var NavigationStore = _.extend({}, EventEmitter.prototype, { - + getGroupIdFromUrl: getGroupIdFromUrl, // Emit Change event emitChange: function() { @@ -29,6 +43,8 @@ var NavigationStore = _.extend({}, EventEmitter.prototype, { }); + + // Register callback with AppDispatcher NavigationStore.dispatchToken = AppDispatcher.register(function(payload) { var action = payload.action;