diff --git a/Gemfile b/Gemfile index 905d01e3..0bb9fcbb 100644 --- a/Gemfile +++ b/Gemfile @@ -23,8 +23,9 @@ group :assets do #gem 'twitter-bootstrap-rails' gem 'bootstrap-sass', '~>2.3' #gem 'bourbon' - #gem 'compass-rails' + gem 'compass-rails' gem 'js-routes' + gem "font-awesome-rails" # See https://github.com/sstephenson/execjs#readme for more supported runtimes #gem 'therubyracer', :platforms => :ruby diff --git a/Gemfile.lock b/Gemfile.lock index 95cffb15..1484ae32 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -110,6 +110,7 @@ GEM capybara-webkit (1.1.0) capybara (~> 2.0, >= 2.0.2) json + chunky_png (1.3.0) climate_control (0.0.3) activesupport (>= 3.0) cocaine (0.5.3) @@ -122,6 +123,12 @@ GEM coffee-script-source execjs coffee-script-source (1.7.0) + compass (0.12.4) + chunky_png (~> 1.2) + fssm (>= 0.2.7) + sass (~> 3.2.17) + compass-rails (1.1.6) + compass (>= 0.12.2) connection_pool (1.2.0) cookiejar (0.3.2) couchbase (1.3.6) @@ -194,9 +201,12 @@ GEM faye-websocket (0.7.2) eventmachine (>= 0.12.0) websocket-driver (>= 0.3.1) + font-awesome-rails (4.0.3.1) + railties (>= 3.2, < 5.0) foundation-rails (5.2.1.0) railties (>= 3.1.0) sass (>= 3.2.0) + fssm (0.2.10) fuubar (1.3.2) rspec (>= 2.14.0, < 3.1.0) ruby-progressbar (~> 1.3) @@ -389,6 +399,7 @@ DEPENDENCIES capybara-webkit cmtool! coffee-rails + compass-rails couch_potato! couchbase couchbase-docstore @@ -401,6 +412,7 @@ DEPENDENCIES emblem-rails factory_girl_rails faye + font-awesome-rails foundation-rails fuubar jquery-rails diff --git a/app/assets/javascripts/shared-ember-helpers/image_tag.js.coffee b/app/assets/javascripts/shared-ember-helpers/image_tag.js.coffee new file mode 100644 index 00000000..64d7cfb5 --- /dev/null +++ b/app/assets/javascripts/shared-ember-helpers/image_tag.js.coffee @@ -0,0 +1,2 @@ +Ember.Handlebars.registerHelper 'image_tag', (path, params..., options={})-> + new Handlebars.SafeString "\"#{options.alt}\"" diff --git a/app/assets/javascripts/supplier/app/app.js.coffee b/app/assets/javascripts/supplier/app/app.js.coffee index ad0bf597..84143d35 100644 --- a/app/assets/javascripts/supplier/app/app.js.coffee +++ b/app/assets/javascripts/supplier/app/app.js.coffee @@ -1,4 +1,3 @@ Qsupplier.App = Ember.Application.create LOG_TRANSITIONS: true rootElement: '#ember-app-container' -@App = Qsupplier.App diff --git a/app/assets/javascripts/supplier/qsupplier.js.coffee b/app/assets/javascripts/supplier/qsupplier.js.coffee index 9b988722..5a23dce5 100644 --- a/app/assets/javascripts/supplier/qsupplier.js.coffee +++ b/app/assets/javascripts/supplier/qsupplier.js.coffee @@ -3,14 +3,9 @@ root.Qsupplier= watch_events: -> faye = new Faye.Client(event_host) faye.subscribe "/supplier/"+supplier_id, (e)=> + console.log(e) if(e.event == 'new_order') Qsupplier.App.Order.pushByAttriburtes(e.data.order) if Qsupplier.App - # old stuff - body = $('#active-orders-table tbody') - order = new Order(e.data.order) - if body.length - body.append @mustache('#active-order-template', order) - $('.section-table-list-'+order.list_id()).addClass('active_order') else if(e.event == 'list_needs_help') if Qsupplier.App and list = Qsupplier.App.List.findCached(e.data.id) list.markNeedsHelp() @@ -29,18 +24,6 @@ root.Qsupplier= list.markIsPaid() else if e.event == 'list_update' Qsupplier.App.List.updateOrAdd(e.data.list) if Qsupplier.App - # old stuff - list = new List(e.data.list) - row = $('#active-lists-table .list-row-'+list.id()) - content = @mustache('#active-list-template', list) - if row.length then row.replaceWith(content) else $('#active-lists-table tbody').append(content) - table = $('#section-table-'+list.table_id()) - if table.length - table.addClass('section-table-list-'+list.id()) - table.addClass('occupied') - table.addClass('needs_help') if list.needs_help() - table.addClass('needs_payment') if list.needs_payment() - table.addClass('active_order') if list.has_active_orders() else if e.event == 'list_closed' if Qsupplier.App and list = Qsupplier.App.List.findCached(e.data.id) list.markClosed() @@ -68,26 +51,24 @@ root.Qsupplier= Qsupplier.App && Qsupplier.App.List.updateOrAdd(e.data.list) # old stuff - list = new List(e.data.list) - list_row = $('.list-row-'+list.id()) - list_row.find('.table_number').text(list.table_number()).addClass('changed') - list_row.find('.section_title').text(e.data.section_title) - order_rows = $('.of-list-'+list.id()) - order_rows.find('.table_number').text(list.table_number()).addClass('changed') - order_rows.find('.section_title').text(e.data.section_title) - # Move properties from table in section tables view - window.last_data = e.data - from_table = $('#section-table-'+e.data.from_table_id) - to_table = $('#section-table-'+list.table_id()) - if to_table.length - to_table.addClass('section-table-list-'+list.id()) - to_table.addClass('occupied') - to_table.addClass('needs_help') if list.needs_help() - to_table.addClass('needs_payment') if list.needs_payment() - to_table.addClass('active_order') if list.has_active_orders() - from_table.removeClass('occupied needs_help needs_payment active_order section-table-list-'+list.id()) - - + #list = new List(e.data.list) + #list_row = $('.list-row-'+list.id()) + #list_row.find('.table_number').text(list.table_number()).addClass('changed') + #list_row.find('.section_title').text(e.data.section_title) + #order_rows = $('.of-list-'+list.id()) + #order_rows.find('.table_number').text(list.table_number()).addClass('changed') + #order_rows.find('.section_title').text(e.data.section_title) + ## Move properties from table in section tables view + #window.last_data = e.data + #from_table = $('#section-table-'+e.data.from_table_id) + #to_table = $('#section-table-'+list.table_id()) + #if to_table.length + #to_table.addClass('section-table-list-'+list.id()) + #to_table.addClass('occupied') + #to_table.addClass('needs_help') if list.needs_help() + #to_table.addClass('needs_payment') if list.needs_payment() + #to_table.addClass('active_order') if list.has_active_orders() + #from_table.removeClass('occupied needs_help needs_payment active_order section-table-list-'+list.id()) console.log(e) false move_table_to_active_section: (table_id)-> diff --git a/app/assets/javascripts/user/app/app.js.coffee b/app/assets/javascripts/user/app/app.js.coffee new file mode 100644 index 00000000..67d55f2b --- /dev/null +++ b/app/assets/javascripts/user/app/app.js.coffee @@ -0,0 +1,20 @@ +@App = Ember.Application.create + LOG_TRANSITIONS: true + rootElement: '#ember-app-container' +Ember.$.ajaxPrefilter (options) -> + if options.type.toUpperCase() == 'GET' + if auth_token = Qstorage.getItem('auth_token') + if options.data + options.data += "&auth_token=#{auth_token}" + else + options.data = "auth_token=#{auth_token}" + if options.type.toUpperCase() == 'POST' + if auth_token = Qstorage.getItem('auth_token') + options.data ||= {} + options.data.auth_token = auth_token + true +Ember.$.ajaxSetup + error: (jqXHR, textStatus, errorThrown)-> + console.log "Error: #{textStatus}: #{errorThrown}" + if jqXHR.status == 401 + App.__container__.lookup('route:application').unauthorized() diff --git a/app/assets/javascripts/user/app/application.js.coffee b/app/assets/javascripts/user/app/application.js.coffee new file mode 100644 index 00000000..e437e6b1 --- /dev/null +++ b/app/assets/javascripts/user/app/application.js.coffee @@ -0,0 +1,10 @@ +#= require_self +#= require handlebars +#= require ember +#= require ember-data +#= require shared-ember-helpers/all +#= require_directory ./modifications +#= require ./app +#= require user/quser +#= require_tree . +@EmberENV = {FEATURES: {'query-params-new': true}} diff --git a/app/assets/javascripts/user/app/components/modal_dialog_component.js.coffee b/app/assets/javascripts/user/app/components/modal_dialog_component.js.coffee new file mode 100644 index 00000000..8af996d7 --- /dev/null +++ b/app/assets/javascripts/user/app/components/modal_dialog_component.js.coffee @@ -0,0 +1,4 @@ +App.ModalDialogComponent = Ember.Component.extend + actions: + close: -> + @sendAction() diff --git a/app/assets/javascripts/user/app/controllers/application_controller.js.coffee b/app/assets/javascripts/user/app/controllers/application_controller.js.coffee new file mode 100644 index 00000000..93d51126 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/application_controller.js.coffee @@ -0,0 +1,30 @@ +App.ApplicationController = Ember.Controller.extend + notice: '' + actions: + confirmCancel: -> + if cancel = @get('confirm.cancel') + cancel.call(@) + $('#confirm-modal').hide() + clearNotice: -> + @set 'notice', null + openDebugger: -> + debugger + currentPathDidChange: (-> + @set 'notice', '' + ).observes('currentPath') + events: + list_helped: -> @set 'list.needs_help', false + list_needs_help: -> @set 'list.needs_help', true # incoming from other users + list_is_paid: -> @set 'list.needs_payment', false + list_needs_payment: -> @set 'list.needs_payment', true # incoming from other users + + getList: -> + Ember.$.get('/user/list_info.json').then (res)=> + if res.not_present + @set 'list', null + else + @set 'list', App.List.create(res) + @getProducts table_id: @get('list.table_id') + getProducts: (options = {})-> + @store.find('product_category', options).then (product_categories)=> + @controllerFor('list_products').set 'model', product_categories diff --git a/app/assets/javascripts/user/app/controllers/index_controller.js.coffee b/app/assets/javascripts/user/app/controllers/index_controller.js.coffee new file mode 100644 index 00000000..0a3ee165 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/index_controller.js.coffee @@ -0,0 +1 @@ +App.IndexController = Ember.Controller.extend {} diff --git a/app/assets/javascripts/user/app/controllers/list_products_controller.js.coffee b/app/assets/javascripts/user/app/controllers/list_products_controller.js.coffee new file mode 100644 index 00000000..4bed86e7 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/list_products_controller.js.coffee @@ -0,0 +1,7 @@ +App.ListProductsController = Ember.ArrayController.extend + actions: + addProduct: (product)-> + if existing = @store.all('product_order').find((po)-> po.get('product') == product) + existing.increment() + else + @store.createRecord 'product_order', product: product diff --git a/app/assets/javascripts/user/app/controllers/list_products_for_table_controller.js.coffee b/app/assets/javascripts/user/app/controllers/list_products_for_table_controller.js.coffee new file mode 100644 index 00000000..051ac346 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/list_products_for_table_controller.js.coffee @@ -0,0 +1 @@ +App.ListProductsForTableController = Ember.ArrayController.extend {} diff --git a/app/assets/javascripts/user/app/controllers/modal_confirm_controller.js.coffee b/app/assets/javascripts/user/app/controllers/modal_confirm_controller.js.coffee new file mode 100644 index 00000000..f04a7b1e --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/modal_confirm_controller.js.coffee @@ -0,0 +1,8 @@ +App.ModalConfirmController = Ember.ObjectController.extend + actions: + close: -> + @get('model.cancel').call(@) if @get('model.cancel') + @send 'closeModal' + confirm: -> + @get('model.ok').call(@) + @send 'closeModal' diff --git a/app/assets/javascripts/user/app/controllers/modal_controller.js.coffee b/app/assets/javascripts/user/app/controllers/modal_controller.js.coffee new file mode 100644 index 00000000..56661006 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/modal_controller.js.coffee @@ -0,0 +1,4 @@ +App.ModalController = Ember.ObjectController.extend + actions: + close: -> + @send 'closeModal' diff --git a/app/assets/javascripts/user/app/controllers/product_orders_controller.js.coffee b/app/assets/javascripts/user/app/controllers/product_orders_controller.js.coffee new file mode 100644 index 00000000..570403b3 --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/product_orders_controller.js.coffee @@ -0,0 +1,21 @@ +App.ProductOrdersController = Ember.ArrayController.extend + orderTotal: (-> + #Math.round(Math.random()*100) + @get('model').getEach('total').reduce(((sum, total) -> sum + total), 0) + ).property('model.@each.quantity') + actions: + clearProductOrders: -> + @store.all('product_order').toArray().invoke 'unloadRecord' + orderProducts: -> + orders = @store.all('product_order').toArray() + data = orders.map( (order)->order.serialize() ) + dataObject = {order: {}} + for product_order in data + dataObject['order'][product_order.product_id] = product_order.quantity + $.ajax + url: Routes.user_order_selected_products_path() + type: "POST", + data: JSON.stringify(dataObject), + contentType: "application/json", + dataType: 'json' + orders.invoke 'unloadRecord' diff --git a/app/assets/javascripts/user/app/controllers/select_qrcode_controller.js.coffee b/app/assets/javascripts/user/app/controllers/select_qrcode_controller.js.coffee new file mode 100644 index 00000000..88f17eec --- /dev/null +++ b/app/assets/javascripts/user/app/controllers/select_qrcode_controller.js.coffee @@ -0,0 +1,43 @@ +App.SelectQrcodeController = Ember.Controller.extend + actions: + selectQr: (table)-> + Qstorage.setItem 'table_id', table._id + @secured -> + $.getJSON(data_host + '/user/table_info.json?'+@authentication_string+'&table_id='+table._id).then (res)=> + if res.current_table_id + if res.other_supplier + @redirect_to 'user_root', message: 'table_is_from_other_supplier' + else if res.current_table_id == table.table_id + #nothing has changed, show product list + @redirect_to 'list_products' + else if res.current_table_id != table.table_id + if res.occupied + @redirect_to 'user_root', message: 'table_is_occupied' + else if res.reserved + @redirect_to 'user_root', message: 'table_is_reserved' + else if table.closed + @redirect_to 'user_root', message: 'table_is_closed' + else if res.supplier_closed + @redirect_to 'user_root', message: 'supplier_is_closed' + else + ## Offer to move table + @send 'confirm', + title: t('move_table.confirmation_title') + body: t('move_table.confirmation_body') + ok: => + $.post(data_host + '/user/move_table.json', $.extend({table_id: table._id}, @authentication_object), (res2)=> + if res2.occupied + @redirect_to 'user_root', {message: 'move_table.cannot_move_to_occupied_tabe'} + else + @redirect_to 'list_products', {message: 'move_table.moved_to_another_table'} + ) + cancel: => + @redirect_to 'list_products' + else + if res.occupied + @redirect_to 'join_occupied_table', {table_id: table.table_id} + else if res.supplier_closed + @redirect_to 'user_root', {message: 'supplier_is_closed'} + else + #$.post(data_host + '/user/create_list.json', {table_id: table.table_id}, (res)-> Quser.handle_response(res)) + @redirect_to 'list_products_for_table', {table_id: table.table_id} diff --git a/app/assets/javascripts/user/app/models/list.js.coffee b/app/assets/javascripts/user/app/models/list.js.coffee new file mode 100644 index 00000000..e56f76dd --- /dev/null +++ b/app/assets/javascripts/user/app/models/list.js.coffee @@ -0,0 +1 @@ +App.List = Ember.Object.extend {} diff --git a/app/assets/javascripts/user/app/models/product.js.coffee b/app/assets/javascripts/user/app/models/product.js.coffee new file mode 100644 index 00000000..7ec7b997 --- /dev/null +++ b/app/assets/javascripts/user/app/models/product.js.coffee @@ -0,0 +1,6 @@ +attr = DS.attr +App.Product = DS.Model.extend + name: attr 'string' + price: attr 'number' + product_category: DS.belongsTo('product_category') + product_orders: DS.hasMany('product_order') diff --git a/app/assets/javascripts/user/app/models/product_category.js.coffee b/app/assets/javascripts/user/app/models/product_category.js.coffee new file mode 100644 index 00000000..096bf301 --- /dev/null +++ b/app/assets/javascripts/user/app/models/product_category.js.coffee @@ -0,0 +1,4 @@ +attr = DS.attr +App.ProductCategory = DS.Model.extend + name: attr('string') + products: DS.hasMany('product') diff --git a/app/assets/javascripts/user/app/models/product_order.js.coffee b/app/assets/javascripts/user/app/models/product_order.js.coffee new file mode 100644 index 00000000..e22cf449 --- /dev/null +++ b/app/assets/javascripts/user/app/models/product_order.js.coffee @@ -0,0 +1,7 @@ +attr = DS.attr +App.ProductOrder = DS.Model.extend + quantity: attr 'number', defaultValue: 1 + product: DS.belongsTo('product') + increment: -> + @set('quantity', @get('quantity') + 1) + total: (-> @get('quantity') * @get('product.price')).property('quantity') diff --git a/app/assets/javascripts/user/app/modifications/controller_modifications.js.coffee b/app/assets/javascripts/user/app/modifications/controller_modifications.js.coffee new file mode 100644 index 00000000..34d485e5 --- /dev/null +++ b/app/assets/javascripts/user/app/modifications/controller_modifications.js.coffee @@ -0,0 +1,50 @@ +Ember.Controller.reopen + needs: ['application'] + secured: (callback)-> + unless Qstorage.getItem('auth_token') && typeof(Qstorage.getItem('auth_token')) == 'string' && Qstorage.getItem('auth_token').length > 0 + return @transitionToRoute('obtain_token') + @authentication_string = 'auth_token='+Qstorage.getItem('auth_token') + @authentication_object = {auth_token: Qstorage.getItem('auth_token')} + callback.call(@) if callback + redirect_to: (route, options={})-> + route = 'index' if route == 'user_root' + @transitionToRoute(route).then => + if options.message + tkey = if options.message.indexOf('.') > -1 then options.message else "messages.#{options.message}" + @set 'controllers.application.notice', t(tkey) + #confirm: (options = {})-> + ##@showModal options + ##$(document).foundation('reflow') # needed (stupid!!!) + #r = @container.lookup('route:application') + #r.send('confirm', options) + ##window.confirm_cancel = options.cancel + ##window.confirm_ok = options.ok + ##$('#confirm-modal .confirm-title').html options.title if options.title + ##$('#confirm-modal .confirm-content').html options.content if options.content + ##@set 'controllers.application.confirm.content', options.content if options.content + ##$('#confirm-modal').foundation('reveal', 'open') # this kills the ember actions + ##$('#confirm-modal').css('visibility', 'visible').show() + showModal: (options={})-> + #this.container.lookup('view:modal', {title:'Test title'}) + debugger + $(document).foundation('reflow') # needed (stupid!!!) + @confirm_cancel = options.cancel + @set 'controllers.application.modal.title', options.title if options.title + @set 'controllers.application.modal.content', options.content if options.content + #$('#confirm-modal').foundation('reveal', 'open') #this kills the ember actions + #$('#confirm-modal').css('visibility', 'visible').show() + +Ember.ArrayController.reopen + needs: ['application'] + secured: (callback)-> + unless Qstorage.getItem('auth_token') && typeof(Qstorage.getItem('auth_token')) == 'string' && Qstorage.getItem('auth_token').length > 0 + return @transitionToRoute('obtain_token') + @authentication_string = 'auth_token='+Qstorage.getItem('auth_token') + @authentication_object = {auth_token: Qstorage.getItem('auth_token')} + callback.call(@) if callback + redirect_to: (route, options={})-> + route = 'index' if route == 'user_root' + @transitionToRoute(route).then => + if options.message + tkey = if options.message.indexOf('.') > -1 then options.message else "messages.#{options.message}" + @set 'controllers.application.notice', t(tkey) diff --git a/app/assets/javascripts/user/app/router.js.coffee b/app/assets/javascripts/user/app/router.js.coffee new file mode 100644 index 00000000..be535ba4 --- /dev/null +++ b/app/assets/javascripts/user/app/router.js.coffee @@ -0,0 +1,14 @@ +# For more information see: http://emberjs.com/guides/routing/ +# and for queryParams: https://github.com/alexspeller/website/blob/a96d9afe4506454b155cc64299e86e558ce3c9f1/source/guides/routing/query-params.md +App.Router.reopen + #location: 'history' + rootURL: '/user' + activate: (a,b,c)-> + debugger + +App.Router.map -> + @route 'select_qrcode' + @route 'obtain_token' + @route 'active_list' + @route 'list_products' + @route 'list_products_for_table' diff --git a/app/assets/javascripts/user/app/routes/application_route.js.coffee b/app/assets/javascripts/user/app/routes/application_route.js.coffee new file mode 100644 index 00000000..84072968 --- /dev/null +++ b/app/assets/javascripts/user/app/routes/application_route.js.coffee @@ -0,0 +1,45 @@ +App.ApplicationRoute = Ember.Route.extend + setupController: (controller)-> + @controllerFor('product_orders').set 'model', @store.all('product_order') + controller.secured -> + faye = new Faye.Client(event_host) + user_id = Qstorage.getItem('user_id') + faye.subscribe "/user/"+user_id, (e)=> + console.log e + @events[e.event].call(@) if @events[e.event] + @getList() + + unauthorized: -> + Qstorage.setItem('auth_token', '') + @controllerFor('application').set 'list', null + @transitionTo('obtain_token').then => + @controllerFor('application').set('notice', t('messages.unauthorized')) + actions: + openModal: (modalName, model)-> + @controllerFor(modalName).set('model', model) + @render modalName, + into: 'application' + outlet: 'modal' + closeModal: -> + @disconnectOutlet + outlet: 'modal' + parentView: 'application' + confirm: (options = {})-> + @send 'openModal', 'modal_confirm', Ember.Object.create + title: options.title + body: options.body + cancel: options.cancel + ok: options.ok + listNeedsPayment: -> + @get('controller').secured -> + $.post(data_host + '/user/list_needs_payment.json', @authentication_object).then (res) => + @set('list.needs_payment', true) + listNeedsHelp: -> + @get('controller').secured -> + $.post(data_host + '/user/needs_help.json', @authentication_object).then (res) => + @set('list.needs_help', true) + scanQr: -> + @transitionTo 'select_qrcode' + events: -> + error: (error)-> + debugger diff --git a/app/assets/javascripts/user/app/routes/list_products_for_table_route.js.coffee b/app/assets/javascripts/user/app/routes/list_products_for_table_route.js.coffee new file mode 100644 index 00000000..48b3ac02 --- /dev/null +++ b/app/assets/javascripts/user/app/routes/list_products_for_table_route.js.coffee @@ -0,0 +1,18 @@ +App.ListProductsForTableRoute = Ember.Route.extend {} + #setupController: (controller)-> + #controller.secured -> + #src = '/user/list_products_for_table.json' + #data = {} + #$.getJSON(data_host + src, $.extend(@authentication_object, data)).then (res) => + #if res.not_present + #@redirect_to 'index', message: 'the_list_has_been_closed' + #return + #for pc in res.categories + #product_category = @store.createRecord 'product_category', + #name: pc.name + #for pp in pc.products + #pp.id = pp._id + #pp.product_category = product_category + #product = @store.createRecord 'product', pp + #controller.set 'model', @store.all('product_category') + #debugger diff --git a/app/assets/javascripts/user/app/routes/list_products_route.js.coffee b/app/assets/javascripts/user/app/routes/list_products_route.js.coffee new file mode 100644 index 00000000..0d18148b --- /dev/null +++ b/app/assets/javascripts/user/app/routes/list_products_route.js.coffee @@ -0,0 +1,17 @@ +App.ListProductsRoute = Ember.Route.extend {} + #setupController: (controller)-> + #controller.secured -> + #src = '/user/list_products.json' + #data = {} + #$.getJSON(data_host + src, $.extend(@authentication_object, data)).then (res) => + #if res.not_present + #@redirect_to 'index', message: 'the_list_has_been_closed' + #return + #for pc in res.categories + #product_category = @store.createRecord 'product_category', + #name: pc.name + #for pp in pc.products + #pp.id = pp._id + #pp.product_category = product_category + #product = @store.createRecord 'product', pp + #controller.set 'model', @store.all('product_category') diff --git a/app/assets/javascripts/user/app/routes/select_qrcode_route.js.coffee b/app/assets/javascripts/user/app/routes/select_qrcode_route.js.coffee new file mode 100644 index 00000000..1b78d951 --- /dev/null +++ b/app/assets/javascripts/user/app/routes/select_qrcode_route.js.coffee @@ -0,0 +1,9 @@ +App.SelectQrcodeRoute = Ember.Route.extend + setupController: (controller)-> + $.ajax + url: Routes.select_qrcode_path() + type: "GET" + dataType: 'json' + async: false + success: (res)-> + controller.set 'tables', res diff --git a/app/assets/javascripts/user/app/store.js.coffee b/app/assets/javascripts/user/app/store.js.coffee new file mode 100644 index 00000000..8eded371 --- /dev/null +++ b/app/assets/javascripts/user/app/store.js.coffee @@ -0,0 +1,13 @@ +# http://emberjs.com/guides/models/defining-a-store/ +DS.RESTAdapter.reopen + namespace: 'user' + +App.ApplicationSerializer = DS.ActiveModelSerializer +App.CustomAdapter = DS.RESTAdapter.extend + + # user underscored paths + pathForType: (type)-> + decamelized = Ember.String.decamelize(type) + Ember.String.pluralize(decamelized) +App.Store = DS.Store.extend + adapter: App.CustomAdapter diff --git a/app/assets/javascripts/user/app/templates/active_list.emblem b/app/assets/javascripts/user/app/templates/active_list.emblem new file mode 100644 index 00000000..b8b191ed --- /dev/null +++ b/app/assets/javascripts/user/app/templates/active_list.emblem @@ -0,0 +1 @@ +h2 Active list diff --git a/app/assets/javascripts/user/app/templates/application.emblem b/app/assets/javascripts/user/app/templates/application.emblem new file mode 100644 index 00000000..9a1d9786 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/application.emblem @@ -0,0 +1,42 @@ +.top-menu.off-canvas-wrap + .inner-wrap + nav.tab-bar + section.left-small + a.left-off-canvas-toggle.menu-icon + span + section.right.tab-bar-section + = link-to 'index' + = image_tag 'icons/logo-small.png' + a{action openDebugger} alt="" + span.fa.fa-wrench.fa-lg + .right + if list.id + App.MenuItemView route="active_list" + App.MenuItemView route='list_products' + App.MenuItemListNeedsHelpView + App.MenuItemListNeedsPaymentView + aside.left-off-canvas-menu + ul.off-canvas-list + li + label Menu + li + = link-to 'index' + span Home + li + a{action scanQr bubbles=false} + span Scan QR + li + =link-to 'list_products' + span= t 'list_products.title' + li + =link-to 'active_list' + span= t 'active_list.title' + section.main-section + if notice + #notice.alert-box{action clearNotice} data-alert=true + a.right href="#" + span.fa.fa-times.fa-lg + span= notice + = outlet + a.exit-off-canvas +=outlet modal diff --git a/app/assets/javascripts/user/app/templates/components/modal-dialog.emblem b/app/assets/javascripts/user/app/templates/components/modal-dialog.emblem new file mode 100644 index 00000000..8e3466bf --- /dev/null +++ b/app/assets/javascripts/user/app/templates/components/modal-dialog.emblem @@ -0,0 +1,2 @@ +.overlay{action "close"} + .modal{action bubbles=false preventDefault=false}= yield diff --git a/app/assets/javascripts/user/app/templates/index.emblem b/app/assets/javascripts/user/app/templates/index.emblem new file mode 100644 index 00000000..43a8396b --- /dev/null +++ b/app/assets/javascripts/user/app/templates/index.emblem @@ -0,0 +1,6 @@ +.home-panel + .home-header = image_tag 'logo.png' + .home-center + a{action scanQr} href="#"= image_tag 'scan-logo.png' + .home-footer + .home-footer-content diff --git a/app/assets/javascripts/user/app/templates/list_products.emblem b/app/assets/javascripts/user/app/templates/list_products.emblem new file mode 100644 index 00000000..f42c3c4e --- /dev/null +++ b/app/assets/javascripts/user/app/templates/list_products.emblem @@ -0,0 +1,9 @@ +.row + .large-6.columns + each product_category in controller + hr + h4= product_category.name + hr + each product in product_category.products + a{action addProduct product}= product.name + .large-6.columns= render 'product_orders' diff --git a/app/assets/javascripts/user/app/templates/list_products_for_table.emblem b/app/assets/javascripts/user/app/templates/list_products_for_table.emblem new file mode 100644 index 00000000..e15ea428 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/list_products_for_table.emblem @@ -0,0 +1,8 @@ +.row + .large-6.columns + each product_category in controller + hr + h4= product_category.name + hr + each product in product_category.products + a{action addProduct product}= product.name diff --git a/app/assets/javascripts/user/app/templates/menu_item_active_list.emblem b/app/assets/javascripts/user/app/templates/menu_item_active_list.emblem new file mode 100644 index 00000000..e0044975 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/menu_item_active_list.emblem @@ -0,0 +1 @@ +span.fa.fa-list.fa-lg diff --git a/app/assets/javascripts/user/app/templates/menu_item_list_needs_help.emblem b/app/assets/javascripts/user/app/templates/menu_item_list_needs_help.emblem new file mode 100644 index 00000000..55a1cbac --- /dev/null +++ b/app/assets/javascripts/user/app/templates/menu_item_list_needs_help.emblem @@ -0,0 +1 @@ +span.needs-help.fa.fa-hand-o-up.fa-lg diff --git a/app/assets/javascripts/user/app/templates/menu_item_list_needs_payment.emblem b/app/assets/javascripts/user/app/templates/menu_item_list_needs_payment.emblem new file mode 100644 index 00000000..995283bf --- /dev/null +++ b/app/assets/javascripts/user/app/templates/menu_item_list_needs_payment.emblem @@ -0,0 +1 @@ +span.needs-payment.fa.fa-money.fa-lg diff --git a/app/assets/javascripts/user/app/templates/menu_item_list_products.emblem b/app/assets/javascripts/user/app/templates/menu_item_list_products.emblem new file mode 100644 index 00000000..9f44b849 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/menu_item_list_products.emblem @@ -0,0 +1,2 @@ +span.fa.fa-cutlery +span.fa.fa-glass diff --git a/app/assets/javascripts/user/app/templates/modal.emblem b/app/assets/javascripts/user/app/templates/modal.emblem new file mode 100644 index 00000000..7bd6e23d --- /dev/null +++ b/app/assets/javascripts/user/app/templates/modal.emblem @@ -0,0 +1,4 @@ +modal-dialog action="close" + h3.flush--top Alert + p= body + button{action "close"} Done diff --git a/app/assets/javascripts/user/app/templates/modal_confirm.emblem b/app/assets/javascripts/user/app/templates/modal_confirm.emblem new file mode 100644 index 00000000..5e76a190 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/modal_confirm.emblem @@ -0,0 +1,6 @@ +modal-dialog action="close" + h3.flush--top= title + p=body + hr + button{action "close"}= t 'confirm.cancel' + button.right{action 'confirm'}= t 'confirm.confirm' diff --git a/app/assets/javascripts/user/app/templates/obtain_token.emblem b/app/assets/javascripts/user/app/templates/obtain_token.emblem new file mode 100644 index 00000000..cfcd3437 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/obtain_token.emblem @@ -0,0 +1 @@ +h3 Obtain token... diff --git a/app/assets/javascripts/user/app/templates/product_orders.emblem b/app/assets/javascripts/user/app/templates/product_orders.emblem new file mode 100644 index 00000000..1fa2087e --- /dev/null +++ b/app/assets/javascripts/user/app/templates/product_orders.emblem @@ -0,0 +1,19 @@ +hr.hide-for-medium-up +if model + a.tiny.button.right{action clearProductOrders} href="#" x +.clearfix +.panel + ul.product-orders + each product_order in controller + li + = product_order.quantity + | x + = product_order.product.name + span.currency=currency product_order.total + else + li= t 'product_orders.no_orders' + li.total + = t 'product_orders.total' + span.currency=currency orderTotal +if model + a.tiny.button.right{action orderProducts} href="#"= t 'product_orders.order_button' diff --git a/app/assets/javascripts/user/app/templates/select_qrcode.emblem b/app/assets/javascripts/user/app/templates/select_qrcode.emblem new file mode 100644 index 00000000..e687625f --- /dev/null +++ b/app/assets/javascripts/user/app/templates/select_qrcode.emblem @@ -0,0 +1,2 @@ +each table in tables + img{action selectQr table} src="/table_qr_image.svg?table_id=#{unbound table._id}" diff --git a/app/assets/javascripts/user/app/views/menu_item_list_needs_help_view.js.coffee b/app/assets/javascripts/user/app/views/menu_item_list_needs_help_view.js.coffee new file mode 100644 index 00000000..4e5cfa53 --- /dev/null +++ b/app/assets/javascripts/user/app/views/menu_item_list_needs_help_view.js.coffee @@ -0,0 +1,10 @@ +App.MenuItemListNeedsHelpView = Ember.View.extend Ember.ViewTargetActionSupport, + action: 'listNeedsHelp' + templateName: "menu_item_list_needs_help" + classNames: 'menu-list-item' + classNameBindings: ['controller.list.needs_help:active'] + click: -> + if @get('controller.list.needs_help') + @set 'controller.notice', t('list_needs_help.help_is_on_its_way') + else + @triggerAction() diff --git a/app/assets/javascripts/user/app/views/menu_item_list_needs_payment_view.js.coffee b/app/assets/javascripts/user/app/views/menu_item_list_needs_payment_view.js.coffee new file mode 100644 index 00000000..b4a05e42 --- /dev/null +++ b/app/assets/javascripts/user/app/views/menu_item_list_needs_payment_view.js.coffee @@ -0,0 +1,11 @@ +App.MenuItemListNeedsPaymentView = Ember.View.extend Ember.ViewTargetActionSupport, + action: 'listNeedsPayment' + templateName: "menu_item_list_needs_payment" + classNames: 'menu-list-item' + classNameBindings: ['controller.list.needs_payment:active'] + click: -> + if @get('controller.list.needs_payment') + @set 'controller.notice', t('list_needs_payment.payment_already_requested') + else + @triggerAction() #action: 'listNeedsPayment' + diff --git a/app/assets/javascripts/user/app/views/menu_item_view.js.coffee b/app/assets/javascripts/user/app/views/menu_item_view.js.coffee new file mode 100644 index 00000000..6db2588c --- /dev/null +++ b/app/assets/javascripts/user/app/views/menu_item_view.js.coffee @@ -0,0 +1,12 @@ +App.MenuItemView = Ember.View.extend + classNames: 'menu-list-item' + classNameBindings: ['active'] + click: -> + @get('controller').transitionToRoute(@route) + active: (-> + if @get('controller.currentPath') == @route then 'active' else '' + ).property('controller.currentPath') + init: -> + @templateName = "menu_item_#{@route}" + @_super() + diff --git a/app/assets/javascripts/user/app/views/modal_view.js.coffee b/app/assets/javascripts/user/app/views/modal_view.js.coffee new file mode 100644 index 00000000..0b12acf8 --- /dev/null +++ b/app/assets/javascripts/user/app/views/modal_view.js.coffee @@ -0,0 +1,10 @@ +#App.ModalView = Ember.View.extend + #templateName: "modal" + #title: "" + #classNames: ["reveal-modal"], + #didInsertElement: -> + ##this.$().foundation('reveal', 'open') + #actions: + #close: -> + #console.log('close action fired') + #this.destroy() diff --git a/app/assets/javascripts/user/application.js.erb b/app/assets/javascripts/user/application.js.erb index 7dd2ceb0..68b34f00 100644 --- a/app/assets/javascripts/user/application.js.erb +++ b/app/assets/javascripts/user/application.js.erb @@ -48,11 +48,13 @@ var $translations = { messages: <%= I18n.t('messages', locale: :en).to_json %>, confirmations: { }, + // Moved to yml list_needs_help: { help_is_on_its_way: 'Help is already on its way', title: 'Request a waiter', content: 'Request a waiter to your table' }, + // Moved to yml list_needs_payment: { payment_already_requested: 'You already asked for the bill', title: 'Ask for the check', @@ -75,6 +77,7 @@ var $translations = { waiting_for_confirmation: 'Waiting for approval of the person on this table...' } }, + // Moved to yml move_table: { cannot_move_to_occupied_table: 'You cannot move to an occupied table', moved_to_another_table: 'The table is changed.', @@ -89,11 +92,13 @@ var $translations = { messages: <%= I18n.t('messages', locale: :nl).to_json %>, confirmations: { }, + // Moved to yml list_needs_help: { help_is_on_its_way: 'Er wordt al iemand naar je tafel gestuurd', title: 'Ik heb een vraag', content: 'Wil je een vraag stellen?' }, + // Moved to yml list_needs_payment: { payment_already_requested: 'De rekening is reeds gevraagd', title: 'Vraag om de rekening', diff --git a/app/assets/javascripts/user/flat/application.js.coffee.erb b/app/assets/javascripts/user/flat/application.js.coffee.erb new file mode 100644 index 00000000..28c1dc2a --- /dev/null +++ b/app/assets/javascripts/user/flat/application.js.coffee.erb @@ -0,0 +1,21 @@ +#= require jquery +#= require jquery_ujs +#= require ../app/application +#= require faye +#= require foundation/foundation +#= require foundation/foundation.offcanvas +#= require moment +#= require jquery.ui.datepicker +#= require translations +#= require js-routes +#= require_directory . +#= require_self + +@Qstorage = localStorage + +$.extend($translations.en, <%= I18n.t('user', locale: :en).to_json %>); +$.extend($translations.nl, <%= I18n.t('user', locale: :nl).to_json %>); +$(document).foundation() +setLocale('en') +$ -> + $('.main-section').css 'min-height', ($(window).height() - $('.tab-bar:first').outerHeight()) diff --git a/app/assets/javascripts/waiter/app/controllers/table_controller.js.coffee b/app/assets/javascripts/waiter/app/controllers/table_controller.js.coffee index 065427dc..178c3c9e 100644 --- a/app/assets/javascripts/waiter/app/controllers/table_controller.js.coffee +++ b/app/assets/javascripts/waiter/app/controllers/table_controller.js.coffee @@ -5,8 +5,8 @@ App.TableController = Ember.ObjectController.extend actions: clearProductOrders: -> - @get('product_orders').toArray().forEach (product_order)-> - product_order.unloadRecord() + # toArray is needed because without is the iterator is not working properly + @get('product_orders').toArray().invoke 'unloadRecord' orderProducts: -> orders = @get('product_orders').toArray() data = orders.map( (order)->order.serialize() ) diff --git a/app/assets/javascripts/waiter/app/templates/table.emblem b/app/assets/javascripts/waiter/app/templates/table.emblem index 2024fc78..1b15435a 100644 --- a/app/assets/javascripts/waiter/app/templates/table.emblem +++ b/app/assets/javascripts/waiter/app/templates/table.emblem @@ -12,11 +12,11 @@ h4 = product_order.quantity | x = product_order.product.name - span.currency=currency product_order.product.price + span.currency=currency product_order.total else - li No products + li= t 'product_orders.no_orders' li.total - | Total + = t 'product_orders.total' span.currency=currency orderTotal if product_orders a.tiny.button.right{action orderProducts} href="#" = t 'product_orders.order_button' diff --git a/app/assets/javascripts/waiter/application.js.coffee.erb b/app/assets/javascripts/waiter/application.js.coffee.erb index e72abda6..d748f29b 100644 --- a/app/assets/javascripts/waiter/application.js.coffee.erb +++ b/app/assets/javascripts/waiter/application.js.coffee.erb @@ -8,6 +8,7 @@ #= require js-routes #= require_directory . #= require_self + @Qstorage = localStorage $.extend($translations.en, <%= I18n.t('waiter', locale: :en).to_json %>); $.extend($translations.nl, <%= I18n.t('waiter', locale: :nl).to_json %>); diff --git a/app/assets/stylesheets/supplier/basic1/application.css b/app/assets/stylesheets/supplier/basic1/application.css index d24917f3..ccb39ff7 100644 --- a/app/assets/stylesheets/supplier/basic1/application.css +++ b/app/assets/stylesheets/supplier/basic1/application.css @@ -4,7 +4,7 @@ *= require 'jquery-ui-1.8.23.custom.css' *= require qtip *= require 'general' - *= require user/active_list + * require user/active_list *= require_directory ../base1-shared *= require_directory . *= require_self diff --git a/app/assets/stylesheets/supplier/wood1/application.css b/app/assets/stylesheets/supplier/wood1/application.css index d24917f3..64fd25f1 100644 --- a/app/assets/stylesheets/supplier/wood1/application.css +++ b/app/assets/stylesheets/supplier/wood1/application.css @@ -4,7 +4,7 @@ *= require 'jquery-ui-1.8.23.custom.css' *= require qtip *= require 'general' - *= require user/active_list + * require active_list *= require_directory ../base1-shared *= require_directory . *= require_self diff --git a/app/assets/stylesheets/user/foundation/application.css.sass b/app/assets/stylesheets/user/foundation/application.css.sass new file mode 100644 index 00000000..ed4e9646 --- /dev/null +++ b/app/assets/stylesheets/user/foundation/application.css.sass @@ -0,0 +1,3 @@ +//= require foundation +//= require font-awesome +//= require_directory . diff --git a/app/assets/stylesheets/user/foundation/index.css.sass b/app/assets/stylesheets/user/foundation/index.css.sass new file mode 100644 index 00000000..8d889536 --- /dev/null +++ b/app/assets/stylesheets/user/foundation/index.css.sass @@ -0,0 +1,12 @@ +@import foundation +.home-panel + +panel() + margin: 30px auto 20px auto + width: 350px + text-align: center + padding-bottom: 30px + .home-header + img + display: block + margin: 0 auto + margin-bottom: 24px diff --git a/app/assets/stylesheets/user/foundation/modal.css.sass b/app/assets/stylesheets/user/foundation/modal.css.sass new file mode 100644 index 00000000..5fbbe4f4 --- /dev/null +++ b/app/assets/stylesheets/user/foundation/modal.css.sass @@ -0,0 +1,16 @@ +.modal + margin: 10px auto + width: 300px + background-color: #fff + padding: 1em + +.overlay + height: 100% + width: 100% + position: fixed + top: 0 + left: 0 + background-color: rgba(0, 0, 0, 0.2) + +.flush--top + margin-top: 0 diff --git a/app/assets/stylesheets/user/foundation/product-orders.css.sass b/app/assets/stylesheets/user/foundation/product-orders.css.sass new file mode 100644 index 00000000..c7106d7a --- /dev/null +++ b/app/assets/stylesheets/user/foundation/product-orders.css.sass @@ -0,0 +1,8 @@ +ul.product-orders + list-style: none + li + border-bottom: 1px solid #ccc + &.total + border-bottom: none + border-top: 4px solid #333 + font-weight: bold diff --git a/app/assets/stylesheets/user/foundation/structure.css.sass b/app/assets/stylesheets/user/foundation/structure.css.sass new file mode 100644 index 00000000..056150c7 --- /dev/null +++ b/app/assets/stylesheets/user/foundation/structure.css.sass @@ -0,0 +1,21 @@ +section.main-section + height: 100% +.top-menu + .menu-list-item + float: right + margin-left: 20px + cursor: pointer + border: 0.08em solid #eee + padding: 3px + border-radius: 0.1em + line-height: 1em + margin-top: 10px + &.active + color: yellow + border-color: yellow +#notice + a + color: white +li + span.currency + float: right diff --git a/app/assets/stylesheets/user/_constants.css.sass b/app/assets/stylesheets/user/wood1/_constants.css.sass similarity index 100% rename from app/assets/stylesheets/user/_constants.css.sass rename to app/assets/stylesheets/user/wood1/_constants.css.sass diff --git a/app/assets/stylesheets/user/active_list.css.sass b/app/assets/stylesheets/user/wood1/active_list.css.sass similarity index 100% rename from app/assets/stylesheets/user/active_list.css.sass rename to app/assets/stylesheets/user/wood1/active_list.css.sass diff --git a/app/assets/stylesheets/user/application.css b/app/assets/stylesheets/user/wood1/application.css similarity index 100% rename from app/assets/stylesheets/user/application.css rename to app/assets/stylesheets/user/wood1/application.css diff --git a/app/assets/stylesheets/user/darkstrap.sass b/app/assets/stylesheets/user/wood1/darkstrap.sass similarity index 99% rename from app/assets/stylesheets/user/darkstrap.sass rename to app/assets/stylesheets/user/wood1/darkstrap.sass index 0f9486b0..2a33185a 100644 --- a/app/assets/stylesheets/user/darkstrap.sass +++ b/app/assets/stylesheets/user/wood1/darkstrap.sass @@ -1,5 +1,5 @@ @import compass -@import mixins +@import ./mixins // Contents: // =General diff --git a/app/assets/stylesheets/user/header.css.sass b/app/assets/stylesheets/user/wood1/header.css.sass similarity index 100% rename from app/assets/stylesheets/user/header.css.sass rename to app/assets/stylesheets/user/wood1/header.css.sass diff --git a/app/assets/stylesheets/user/list_products.css.sass b/app/assets/stylesheets/user/wood1/list_products.css.sass similarity index 79% rename from app/assets/stylesheets/user/list_products.css.sass rename to app/assets/stylesheets/user/wood1/list_products.css.sass index 9278d03f..f59500c9 100644 --- a/app/assets/stylesheets/user/list_products.css.sass +++ b/app/assets/stylesheets/user/wood1/list_products.css.sass @@ -1,5 +1,5 @@ @import compass -@import user/constants +@import ./constants #products-table .order-product-button +wood-button diff --git a/app/assets/stylesheets/user/mixins.sass b/app/assets/stylesheets/user/wood1/mixins.sass similarity index 100% rename from app/assets/stylesheets/user/mixins.sass rename to app/assets/stylesheets/user/wood1/mixins.sass diff --git a/app/assets/stylesheets/user/qr_list.css.sass b/app/assets/stylesheets/user/wood1/qr_list.css.sass similarity index 100% rename from app/assets/stylesheets/user/qr_list.css.sass rename to app/assets/stylesheets/user/wood1/qr_list.css.sass diff --git a/app/assets/stylesheets/user/structure.css.sass b/app/assets/stylesheets/user/wood1/structure.css.sass similarity index 99% rename from app/assets/stylesheets/user/structure.css.sass rename to app/assets/stylesheets/user/wood1/structure.css.sass index 00ebb2a4..ccc4a8b9 100644 --- a/app/assets/stylesheets/user/structure.css.sass +++ b/app/assets/stylesheets/user/wood1/structure.css.sass @@ -1,5 +1,5 @@ @import compass -@import user/constants +@import ./constants html background-image: $wood background-color: $background-brown diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 86b3731f..6eb05d60 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -8,8 +8,11 @@ class DashboardController < ApplicationController # Testing action def select_qrcode #@tables = Table.all.sample(2) | List.active.map(&:table) - @tables = Supplier.first.tables.sample(2) | List.active.map(&:table) - render layout: 'phone' + @tables = Supplier.first.tables.sample(5) | List.active.map(&:table) + respond_to do |format| + format.html { render layout: 'phone' } + format.json { render json: @tables.to_json } + end end diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 1d8d0d59..a16e13ea 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -1,41 +1,7 @@ -class UserController < ApplicationController +class UserController < Users::ApplicationController before_filter :allow_mobile - before_filter :user_authentication, :unless => ->(c){ %w(obtain_token index).include?(c.action_name) || c.request.format.symbol == :html } # , except: [:obtain_token, :index] - layout 'phone' - - def user_authentication - if params[:auth_token].present? - user = User.find_by_authentication_token(params[:auth_token]) - sign_in user if user - sign_out current_user if current_user && !user # Other token attempt of logged in user - else - authenticate_user! - end - - unless current_user.present? - respond_to do |format| - format.html {redirect_to new_user_session_path} - format.json {render json: json_response(ok: false, status: 401)} - end - end - end - - def obtain_token - redirect_to user_omniauth_authorize_path('facebook') and return unless current_user.present? - respond_to do |format| - format.html - format.json do - render json: json_response(ok: false, status: 401) and return unless params[:user].present? && params[:user][:email].present? && params[:user][:password].present? - user = User.find_by_email(params[:user][:email]) - render json: json_response(ok: false, status: 401) and return unless user - render json: json_response(ok: false, status: 401) and return unless user.valid_password?(params[:user][:password]) - user.ensure_authentication_token - sign_in user - render json: json_response(ok: true, auth_token: user.authentication_token, user_id: user.id) - end - - end - end + layout 'user/foundation' + #layout 'phone' alias :list :active_list @@ -91,13 +57,17 @@ class UserController < ApplicationController # GET /suppliers/1/product_list # GET /suppliers/1/product_list.json def list_products - redirect_to(user_root_path(message: 'the_list_has_been_closed')) and return unless list - @supplier = list.supplier respond_to do |format| format.html do + redirect_to(user_root_path(message: 'the_list_has_been_closed')) and return unless list + @supplier = list.supplier handle_message_params end format.json do + unless list + render json: {not_present: true} and return + end + @supplier = list.supplier h = ProductCategory.for_user(current_user, table: list.table, list: list, supplier: @supplier) # list is performance parameter render json: h #products = list.supplier.products @@ -291,7 +261,7 @@ class UserController < ApplicationController end format.json do render json: json_alert('messages.cannot_order_on_non_active_list') and return unless @list.active? - @list.place_order params[:products], user: current_user + @list.place_order params[:order] || params[:products], user: current_user render json: json_notice('messages.order_is_placed', location: :active_list) end end @@ -299,6 +269,7 @@ class UserController < ApplicationController def move_table render json: json_alert('messages.no_active_list', list_active: false) and return unless list.present? + render json: json_alert('messages.table_not_found') and return unless params[:table_id].present? @table = Table.find(params[:table_id]) if @table.occupied? render json: {occupied: true} @@ -307,18 +278,4 @@ class UserController < ApplicationController render json: {occupied: false} end end - - private - - def handle_message_params - flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human) if params[:list_closed].present? - flash.now[:notice] = t("messages.#{params[:message]}", list: List.model_name.human, supplier: Supplier.model_name.human) if params[:message].present? && params[:message] =~ /^\w+$/ - end - - # General handler of json responses. Will be able to set some additional communication data. - # By default a response is ok. - def json_response(obj = {}) - obj[:ok] = true unless obj.has_key?(:ok) - obj - end end diff --git a/app/controllers/users/application_controller.rb b/app/controllers/users/application_controller.rb new file mode 100644 index 00000000..da2cab62 --- /dev/null +++ b/app/controllers/users/application_controller.rb @@ -0,0 +1,52 @@ +module Users + class ApplicationController < ::ApplicationController + before_action :user_authentication, :unless => ->(c){ %w(obtain_token).include?(c.action_name) || c.request.format.symbol == :html } # , except: [:obtain_token, :index] + private + + def user_authentication + if params[:auth_token].present? + user = User.find_by_authentication_token(params[:auth_token]) + sign_in user if user + sign_out current_user if current_user && !user # Other token attempt of logged in user + else + authenticate_user! + end + + unless current_user.present? + respond_to do |format| + format.html {redirect_to new_user_session_path} + format.json {render json: json_response(ok: false, status: 401), status: :unauthorized} + end + end + end + + def obtain_token + redirect_to user_omniauth_authorize_path('facebook') and return unless current_user.present? + respond_to do |format| + format.html + format.json do + render json: json_response(ok: false, status: 401) and return unless params[:user].present? && params[:user][:email].present? && params[:user][:password].present? + user = User.find_by_email(params[:user][:email]) + render json: json_response(ok: false, status: 401) and return unless user + render json: json_response(ok: false, status: 401) and return unless user.valid_password?(params[:user][:password]) + user.ensure_authentication_token + sign_in user + render json: json_response(ok: true, auth_token: user.authentication_token, user_id: user.id) + end + + end + end + + def handle_message_params + flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human) if params[:list_closed].present? + flash.now[:notice] = t("messages.#{params[:message]}", list: List.model_name.human, supplier: Supplier.model_name.human) if params[:message].present? && params[:message] =~ /^\w+$/ + end + + # General handler of json responses. Will be able to set some additional communication data. + # By default a response is ok. + def json_response(obj = {}) + obj[:ok] = true unless obj.has_key?(:ok) + obj + end + end +end diff --git a/app/controllers/users/product_categories_controller.rb b/app/controllers/users/product_categories_controller.rb new file mode 100644 index 00000000..81a1353a --- /dev/null +++ b/app/controllers/users/product_categories_controller.rb @@ -0,0 +1,15 @@ +module Users + class ProductCategoriesController < Users::ApplicationController + #EMBER + def index + respond_to do |format| + format.json do + render json: {} and return unless params[:table_id].present? + table = Table.find(params[:table_id]) + product_categories = table.supplier.product_categories.include_relation('products') # not yet implemented for many to many + render json: product_categories #, serializer: ProductCategorySerializer + end + end + end + end +end diff --git a/app/models/order.rb b/app/models/order.rb index 7f871dad..4b05a296 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -108,7 +108,7 @@ class Order def close! self.state = 'closed' if placed? || active? if save - broadcast_user user.id, 'order_closed', id: id + broadcast_user user.id, 'order_closed', id: id if user broadcast_supplier supplier_id, 'order_closed', id: id end end diff --git a/app/templates/user/_list-history.mustache b/app/templates/user/_list_history.mustache similarity index 100% rename from app/templates/user/_list-history.mustache rename to app/templates/user/_list_history.mustache diff --git a/app/views/layouts/phone.html.slim b/app/views/layouts/phone.html.slim index 398d5a13..421a8ad4 100644 --- a/app/views/layouts/phone.html.slim +++ b/app/views/layouts/phone.html.slim @@ -10,7 +10,7 @@ html lang="en" /! Le HTML5 shim, for IE6-8 support of HTML elements /[if lt IE 9] = javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js" - = stylesheet_link_tag "user/application", :media => "all" + = stylesheet_link_tag "user/wood1/application", :media => "all" link href="/images/apple-touch-icon-144x144.png" rel="apple-touch-icon-precomposed" sizes="144x144" link href="/images/apple-touch-icon-114x114.png" rel="apple-touch-icon-precomposed" sizes="114x114" link href="/images/apple-touch-icon-72x72.png" rel="apple-touch-icon-precomposed" sizes="72x72" diff --git a/app/views/layouts/tablet.html.slim b/app/views/layouts/tablet.html.slim index e4d888c0..52e5893d 100644 --- a/app/views/layouts/tablet.html.slim +++ b/app/views/layouts/tablet.html.slim @@ -10,7 +10,7 @@ html lang="en" /! Le HTML5 shim, for IE6-8 support of HTML elements /[if lt IE 9] = javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js" - = stylesheet_link_tag "supplier/basic1/application", media: "all" + = stylesheet_link_tag "supplier/wood1/application", media: "all" link href="/favicon.ico" rel="shortcut icon" = render 'suppliers/application/head' = javascript_include_tag "supplier/application" diff --git a/app/views/layouts/user/foundation.html.slim b/app/views/layouts/user/foundation.html.slim new file mode 100644 index 00000000..f324074f --- /dev/null +++ b/app/views/layouts/user/foundation.html.slim @@ -0,0 +1,47 @@ +doctype html +html lang="en" + head + meta charset="utf-8" + meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" + meta name="viewport" content="width=device-width, initial-scale=1.0" + title Qwaiter + = stylesheet_link_tag "user/foundation/application" + = javascript_include_tag "vendor/modernizr" + = javascript_include_tag "user/flat/application" + - if ENV['QWAITER_MOBILE_EXPORT'] == 'yes' + javascript: + var QMobile, Qwaiter, Quser; + var data_host = 'http://data.qwaiter.com'; + var event_host = '#{Qwaiter.event_host}'; + var $asset_path = '##assets_path##'; + var Qstorage = localStorage; + - else + javascript: + var QMobile, Qwaiter, Quser; + var data_host = 'http://data.qwaiter.com'; + var event_host = '#{Qwaiter.event_host}'; + var $asset_path = '/assets/'; + var Qstorage = localStorage; + #{user_dynamic_data_host} + QMobile || (QMobile = { + scanQr: function(){window.location = '/select_qrcode'}, + activateRotation: function(){}, + mobile: function(){return false}, + authentication_string: function(){return this.authentication_string_storage || ''}, + authentication_object: function(){return this.authentication_object_storage || '{}'}, + setAuthToken: function(token){ + this.auth_token = token; + this.authentication_string_storage = 'auth_token='+token; + this.authentication_object_storage = '{"auth_token": "'+token+'"}' + }, + root_url: function(){return 'file:///Users/bterkuile/Documents/workspace/Qwaiter/assets/user'}, + root_url: function(){return '/user'}, + goHome: function(){ redirect_to('user_root')}, + connection_problem: function(){alert('There is a problem connecting to the server')}, + token: function(){return this.auth_token}, + setUserId: function(id){ this.stored_user_id = id}, + user_id: function(){return this.stored_user_id }, + log: function(str){console.log(str)} + }); + body + #ember-app-container diff --git a/app/views/user/ember.html.slim b/app/views/user/ember.html.slim new file mode 100644 index 00000000..f47f3f9d --- /dev/null +++ b/app/views/user/ember.html.slim @@ -0,0 +1,13 @@ +doctype html +html lang="en" + head + meta charset="utf-8" + meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" + meta name="viewport" content="width=device-width, initial-scale=1.0" + title Qwaiter + /= stylesheet_link_tag "waiter/application", media: "all" + = stylesheet_link_tag "waiter/application" + = javascript_include_tag "vendor/modernizr" + = javascript_include_tag "waiter/application" + body + #ember-app-container diff --git a/app/views/user/list_history.html.slim b/app/views/user/list_history.html.slim index 741bd709..0b6e69cc 100644 --- a/app/views/user/list_history.html.slim +++ b/app/views/user/list_history.html.slim @@ -2,5 +2,5 @@ span nav.pagination ul#list-history-container -script#list-history-template[type="text/html"]= mustache_template 'list-history' +script#list-history-template[type="text/html"]= mustache_template 'list_history' - onload_javascript "Qstorage.page = 1; Quser.load_list_history()" diff --git a/config/application.rb b/config/application.rb index 84eb8379..4d0e8a78 100644 --- a/config/application.rb +++ b/config/application.rb @@ -76,7 +76,7 @@ module Qwaiter config.active_support.escape_html_entities_in_json = true - config.handlebars.templates_root = %w[supplier/app/templates waiter/app/templates] + config.handlebars.templates_root = %w[supplier/app/templates waiter/app/templates user/app/templates] config.generators do |g| g.orm :simply_stored diff --git a/config/locales/en.yml b/config/locales/en.yml index 67f16053..9a850b38 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -32,6 +32,7 @@ en: no_records: There are no items present actions: title: Actions + #depricated, moved to user messages: cannot_order_on_non_active_list: You cannot place an order on a closed list no_active_list: There is no active list diff --git a/config/locales/user.en.yml b/config/locales/user.en.yml index 1c48de79..76a7dd5d 100644 --- a/config/locales/user.en.yml +++ b/config/locales/user.en.yml @@ -1,9 +1,30 @@ en: user: - unknown_supplier_name: unknown + messages: + cannot_order_on_non_active_list: You cannot place an order on a closed list + no_active_list: There is no active list + order_is_placed: Your order has been received in good order + new_list_created: A new ${models.list} has been created + the_list_has_been_closed: The list has been closed + illegal_history_list_attempt: The list you want to access is not yours + table_not_found: The requested table cannot be found or is not given + table_is_occupied: The table you want to sit on is already occupied + table_is_reserved: The table you want to sit on is reserved by someone else + table_is_closed: The table you want to sit on is not available for service + supplier_is_closed: The owner of this table is currently not handling orders + join_request_rejected: Your request to join the table has been rejected + join_request_approved: Your request to join the table has been approved + table_is_from_other_supplier: You cannot move to another table when you have an open list + moved_to_another_table: You successfully moved to another table + cannot_identify_table: The application cannot determine the table number + unknown_supplier_name: unknown + unauthorized: Unauthorized action detected + active_list: title: Active list needs_payment: Check please! + list_products: + title: Order history_list: title: Closed list list_history: @@ -28,3 +49,23 @@ en: title: Authenticate Qwaiter obtain: Authenticate invalid_combination: The email password combination is incorrect + move_table: + cannot_move_to_occupied_table: 'You cannot move to an occupied table' + moved_to_another_table: 'The table is changed.' + confirmation_title: 'Move to another table?' + confirmation_body: 'Do you want to move to another table?' + confirm: + cencel: Cancel + confirm: 'Yes' + list_needs_help: + help_is_on_its_way: 'Help is already on its way' + title: 'Request a waiter' + content: 'Request a waiter to your table' + list_needs_payment: + payment_already_requested: 'You already asked for the bill' + title: 'Ask for the check' + content: 'Do you want to pay?' + product_orders: + order_button: Order + total: Total + no_orders: No products diff --git a/config/locales/user.nl.yml b/config/locales/user.nl.yml index 5efd2002..40d1200d 100644 --- a/config/locales/user.nl.yml +++ b/config/locales/user.nl.yml @@ -1,9 +1,29 @@ nl: user: - unknown_supplier_name: onbekend + messages: + cannot_order_on_non_active_list: Je kan niet bestellen op een gesloten lijst + no_active_list: Er is momenteel geen lijst actief + order_is_placed: Je bestelling is in goede orde aangekomen + new_list_created: Een nieuwe ${models.list} is aangemaakt + the_list_has_been_closed: De lijst is afgesloten + illegal_history_list_attempt: Je probeert een lijst op te vragen die niet van jou is + table_not_found: De gezochte tafel kan niet worden gevonden of is niet opgegeven + table_is_occupied: De tafel waar je aan wil gaan zitten is reeds bezet + table_is_reserved: De tafel waar je aan wil gaan zitten is gereserveerd + table_is_closed: De tafel waar je aan wil gaan zitten is niet beschikbaar voor bediening + supplier_is_closed: De eigenaar van deze tafel is momenteel gesloten + join_request_rejected: Je verzoek om te mogen bestellen op een bestaande lijst is afgewezen + join_request_approved: Je verzoek om te mogen bestellen op een bestaande lijst is goedgekeurd + table_is_from_other_supplier: Je kan geen lijst openen bij een andere zaak zolang je huidige lijst nog niet is afgesloten + moved_to_another_table: De tafel is gewijzigd + cannot_identify_table: De applicatie kan niet bepalen om welke tafel het gaat + unknown_supplier_name: onbekend + unauthorized: Niet toegestane actie active_list: title: Actieve lijst needs_payment: Rekening vragen! + list_products: + title: Bestel history_list: title: Afgesloten lijst list_history: @@ -28,3 +48,23 @@ nl: title: Aanmelden bij Qwaiter obtain: Aanmelden invalid_combination: De inloggegevens zijn onjuist + move_table: + cannot_move_to_occupied_table: 'Je kan niet verhuizen naar een tafel die reeds gebruikt wordt.' + moved_to_another_table: 'De tafel is gewijzigd.' + confirmation_title: 'Naar een andere tafel verhuizen?' + confirmation_body: 'Wil je aan een andere tafel gaan zitten?' + confirm: + cencel: Annuleer + confirm: 'Ja' + list_needs_help: + help_is_on_its_way: 'Er wordt al iemand naar je tafel gestuurd' + title: 'Ik heb een vraag' + content: 'Wil je een vraag stellen?' + list_needs_payment: + payment_already_requested: 'De rekening is reeds gevraagd' + title: 'Vraag om de rekening' + content: 'Wil je betalen?' + product_orders: + order_button: Bestel + total: Totaal + no_orders: Geen bestellingen diff --git a/config/locales/waiter.en.yml b/config/locales/waiter.en.yml index 8cd5e6f7..132aee15 100644 --- a/config/locales/waiter.en.yml +++ b/config/locales/waiter.en.yml @@ -2,3 +2,5 @@ en: waiter: product_orders: order_button: Order + total: Total + no_orders: No products diff --git a/config/locales/waiter.nl.yml b/config/locales/waiter.nl.yml index 76045c62..b2106982 100644 --- a/config/locales/waiter.nl.yml +++ b/config/locales/waiter.nl.yml @@ -2,3 +2,5 @@ nl: waiter: product_orders: order_button: Bestel + total: Totaal + no_orders: Geen bestellingen diff --git a/config/routes.rb b/config/routes.rb index 930809cd..9bb89d36 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,8 +69,12 @@ Qwaiter::Application.routes.draw do get '/user/obtain_token' => 'user#obtain_token', as: :user_obtain_token post '/user/obtain_token' => 'user#obtain_token', constraints: {format: :json} + namespace :users, path: '/user' do + resources :product_categories, only: [:index] + end + + get '/supplier/suppliers/current' => 'supplier#current' #ember - #match '/show_products' => 'dashboard#show_products', as: :user_products # GENERAL diff --git a/spec/acceptance_steps/global_table_steps.rb b/spec/acceptance_steps/global_table_steps.rb index 3212ea0b..284aa8bd 100644 --- a/spec/acceptance_steps/global_table_steps.rb +++ b/spec/acceptance_steps/global_table_steps.rb @@ -6,6 +6,7 @@ end step "another user scans the QR code on the table" do step 'there is another signed in user user' visit user_root_path + binding.pry page.execute_script "Quser.actions_for_table({table_id: '#{@table.id}'})" end diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb index b989e44c..d667eeb0 100644 --- a/spec/models/list_spec.rb +++ b/spec/models/list_spec.rb @@ -125,29 +125,29 @@ describe List do describe '#place_order' do it 'returns an order object' do - list.place_order(user, product.id => 7).should be_a Order + list.place_order(product.id => 7, user: user).should be_a Order end it 'creates an order' do - expect{ list.place_order(user, product.id => 7) }.to change{ Order.count }.by(1) + expect{ list.place_order(product.id => 7, user: user) }.to change{ Order.count }.by(1) end describe 'broadcasting' do it 'broadcasts to the user and the supplier the active order counter' do - list.place_order(user, product.id => 7) + list.place_order(product.id => 7, user: user) expect{ - list.place_order(user, product.id => 3) + list.place_order(product.id => 3, user: user) }.to broadcast_to_user(user.id).message('orders_placed_count').with(count: 2) expect{ - list.place_order(user, product.id => 5) + list.place_order(product.id => 5, user: user) }.to broadcast_to_supplier(supplier.id).message('orders_placed_count').with(count: 3) end end it 'sets the list price as kind of caching' do - list.place_order(user, product.id => 7) + list.place_order(product.id => 7, user: user) list.reload list.price.should == 15.54 end