solidus_auction 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +57 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/javascripts/auctions.js +2 -0
  6. data/app/assets/javascripts/countdown.js +20 -0
  7. data/app/assets/javascripts/local-time.js +1 -0
  8. data/app/assets/javascripts/spree/backend/product_autocomplete.js +50 -0
  9. data/app/assets/javascripts/spree/backend/solidus_auction.js +7 -0
  10. data/app/assets/javascripts/spree/ends_in.js +31 -0
  11. data/app/assets/javascripts/spree/frontend/solidus_auction.js +8 -0
  12. data/app/assets/javascripts/spree/frontend/starts_in.js +32 -0
  13. data/app/assets/javascripts/spree/frontend/votes.js +83 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_auction.css +16 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_auction.css +24 -0
  16. data/app/controllers/spree/admin/auction_settings_controller.rb +16 -0
  17. data/app/controllers/spree/admin/auctions_controller.rb +46 -0
  18. data/app/controllers/spree/admin/bids_controller.rb +2 -0
  19. data/app/controllers/spree/admin/resource_controller_decorator.rb +9 -0
  20. data/app/controllers/spree/auctions_controller.rb +52 -0
  21. data/app/controllers/spree/bids_controller.rb +48 -0
  22. data/app/controllers/spree/helpers/local_time_helper.rb +77 -0
  23. data/app/controllers/spree/users_controller_decorator.rb +5 -0
  24. data/app/controllers/spree/votes_controller.rb +5 -0
  25. data/app/helpers/spree/strong_params_decorator.rb +8 -0
  26. data/app/models/spree/auction.rb +291 -0
  27. data/app/models/spree/auction_ability.rb +13 -0
  28. data/app/models/spree/bid.rb +19 -0
  29. data/app/models/spree/product_decorator.rb +3 -0
  30. data/app/models/spree/user_decorator.rb +5 -0
  31. data/app/models/spree/variant_decorator.rb +3 -0
  32. data/app/overrides/add_auction_links_to_order_info.rb +6 -0
  33. data/app/overrides/add_auction_settings_tab.rb +8 -0
  34. data/app/overrides/add_auctions_tab_to_admin.rb +8 -0
  35. data/app/overrides/add_auctions_table_to_user_show.rb +6 -0
  36. data/app/overrides/add_auctions_to_main_nav.rb +6 -0
  37. data/app/overrides/add_timezone_to_admin.rb +8 -0
  38. data/app/overrides/change_line_item_delete_button.rb +6 -0
  39. data/app/overrides/change_line_item_link_to.rb +6 -0
  40. data/app/overrides/change_line_item_number_field_disabled.rb +6 -0
  41. data/app/overrides/change_order_item_description.rb +6 -0
  42. data/app/overrides/change_stock_item_name.rb +6 -0
  43. data/app/overrides/change_variant_row_show.rb +6 -0
  44. data/app/overrides/change_variant_stock_item_show.rb +6 -0
  45. data/app/validators/in_future_validator.rb +10 -0
  46. data/app/views/spree/admin/active_shipping_settings/edit.html.erb +108 -0
  47. data/app/views/spree/admin/auction_settings/edit.html.erb +45 -0
  48. data/app/views/spree/admin/auctions/_form.html.erb +189 -0
  49. data/app/views/spree/admin/auctions/edit.html.erb +18 -0
  50. data/app/views/spree/admin/auctions/index.html.erb +89 -0
  51. data/app/views/spree/admin/auctions/new.html.erb +14 -0
  52. data/app/views/spree/admin/shared/_auction_links_to_order_info.html.erb +18 -0
  53. data/app/views/spree/admin/shared/_auction_settings_button.html.erb +3 -0
  54. data/app/views/spree/admin/shared/_auctions_tab.html.erb +3 -0
  55. data/app/views/spree/admin/shared/_time_zone_field.html.erb +5 -0
  56. data/app/views/spree/auctions/_bid_form.html.erb +81 -0
  57. data/app/views/spree/auctions/_bids.html.erb +52 -0
  58. data/app/views/spree/auctions/_image.html.erb +5 -0
  59. data/app/views/spree/auctions/_promotions.html.erb +19 -0
  60. data/app/views/spree/auctions/_properties.html.erb +15 -0
  61. data/app/views/spree/auctions/_taxons.html.erb +14 -0
  62. data/app/views/spree/auctions/_thumbnails.html.erb +19 -0
  63. data/app/views/spree/auctions/index.html.erb +3 -0
  64. data/app/views/spree/auctions/show.html.erb +58 -0
  65. data/app/views/spree/bids/index.html.erb +0 -0
  66. data/app/views/spree/bids/new.html.erb +0 -0
  67. data/app/views/spree/products/_cart_form.html.erb +65 -0
  68. data/app/views/spree/products/_promotions.html.erb +19 -0
  69. data/app/views/spree/products/_properties.html.erb +15 -0
  70. data/app/views/spree/products/_taxons.html.erb +14 -0
  71. data/app/views/spree/products/_thumbnails.html.erb +19 -0
  72. data/app/views/spree/products/index.html.erb +15 -0
  73. data/app/views/spree/products/show.html.erb +51 -0
  74. data/app/views/spree/shared/_auction_order_link.html.erb +9 -0
  75. data/app/views/spree/shared/_auctions.html.erb +39 -0
  76. data/app/views/spree/shared/_auctions_link.html.erb +7 -0
  77. data/app/views/spree/shared/_auctions_table_show.html.erb +93 -0
  78. data/app/views/spree/shared/_ends_in.html.erb +14 -0
  79. data/app/views/spree/shared/_image.html.erb +12 -0
  80. data/app/views/spree/shared/_line_item_delete.html.erb +5 -0
  81. data/app/views/spree/shared/_line_item_link_to.erb +22 -0
  82. data/app/views/spree/shared/_line_item_number_field_disabled.erb +9 -0
  83. data/app/views/spree/shared/_order_item_description.html.erb +15 -0
  84. data/app/views/spree/shared/_starts_in.html.erb +14 -0
  85. data/app/views/spree/shared/_stock_item_name.html.erb +5 -0
  86. data/app/views/spree/shared/_time_in_words_display.html.erb +11 -0
  87. data/app/views/spree/shared/_variant_row_disable.html.erb +21 -0
  88. data/app/views/spree/shared/_variant_stock_item_disable.html.erb +62 -0
  89. data/app/views/spree/shared/_votes.html.erb +12 -0
  90. data/app/views/spree/votes/index.html.erb +13 -0
  91. data/config/locales/en.yml +76 -0
  92. data/config/routes.rb +17 -0
  93. data/db/migrate/20180225234309_create_auctions.rb +25 -0
  94. data/db/migrate/20180225235226_create_bids.rb +13 -0
  95. data/db/migrate/20180316051158_add_deleted_to_spree_auction.rb +5 -0
  96. data/db/migrate/20180320010358_change_auction_reserve_price_column_to_big_decimal.rb +8 -0
  97. data/db/migrate/20180321203019_add_time_zone_to_spree_user.rb +5 -0
  98. data/db/migrate/20180322014713_add_default_to_datetimes.rb +7 -0
  99. data/db/migrate/20180328233438_add_variant_id_to_auction.rb +5 -0
  100. data/db/migrate/20180410025053_acts_as_votable_migration.rb +22 -0
  101. data/db/migrate/20180410031333_add_cached_votes_to_spree_auctions.rb +13 -0
  102. data/lib/assets/javascripts/src/local-time/calendar_date.coffee +37 -0
  103. data/lib/assets/javascripts/src/local-time/config/i18n.coffee +74 -0
  104. data/lib/assets/javascripts/src/local-time/config/locale.coffee +2 -0
  105. data/lib/assets/javascripts/src/local-time/config/timer.coffee +1 -0
  106. data/lib/assets/javascripts/src/local-time/controller.coffee +59 -0
  107. data/lib/assets/javascripts/src/local-time/helpers/date_parse.coffee +15 -0
  108. data/lib/assets/javascripts/src/local-time/helpers/dom.coffee +11 -0
  109. data/lib/assets/javascripts/src/local-time/helpers/i18n.coffee +24 -0
  110. data/lib/assets/javascripts/src/local-time/helpers/strftime.coffee +55 -0
  111. data/lib/assets/javascripts/src/local-time/index.coffee +20 -0
  112. data/lib/assets/javascripts/src/local-time/page_observer.coffee +43 -0
  113. data/lib/assets/javascripts/src/local-time/relative_time.coffee +72 -0
  114. data/lib/assets/javascripts/src/local-time/start.coffee +25 -0
  115. data/lib/generators/solidus_auction/install/install_generator.rb +30 -0
  116. data/lib/local_time.rb +0 -0
  117. data/lib/solidus_auction.rb +3 -0
  118. data/lib/solidus_auction/configuration.rb +8 -0
  119. data/lib/solidus_auction/engine.rb +29 -0
  120. data/lib/solidus_auction/factories.rb +19 -0
  121. data/lib/solidus_auction/version.rb +3 -0
  122. metadata +388 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ed967ff89e313e5a77ce9ad7074c006f24a894b87bab2384ed196875e8f66bd1
4
+ data.tar.gz: d4161f99b72d9b3c01ad202a8f9f7b82216b5f88fc422a6f8e9d9fcff9812eb6
5
+ SHA512:
6
+ metadata.gz: eddeb43728e17fc6d9f3a5928fb1afab5c46e4a895c3ba211f7b139ed9f19883df42dbbd7ddc56e03d380e006cc4ca6764f368aa8f85f44fef413ccfb7f18c84
7
+ data.tar.gz: e28c54950a8b96150d41d293cf26ae6f2cfb44b642eebd774b62cdae813c9de4bde444e27952541527982ac994ac152157acb43ae5eb0d4d4370a2a5181394fe
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2018 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Spree nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,57 @@
1
+ Solidus Auction
2
+ ==============
3
+ [![Build Status](https://travis-ci.org/jgujgu/solidus_auction.svg?branch=master)](https://travis-ci.org/jgujgu/solidus_auction)
4
+
5
+ This extension adds auction items, bidding, views, and admin pages to an existing Solidus store. Namely, it allows the creation of auctions for specific store items. It retains the existing fulfillment flow.
6
+
7
+ Its bidding mechanism is similar to eBay's in that it allows bidders to submit very high bids that "autobid" for them, up to that original bid's price in increments set by the auction (or their opponents). See [eBay's explanation](http://pages.ebay.com/help/buy/bidding-overview.html#auto) for more details.
8
+
9
+ More specifically, when an auction completes, a `Spree::Variant` with the `Auction.current_price` and tied to the auction's `Spree::Product` gets created. This `Spree::Variant` differs from the normal kind because typically it needs an `option_value` (such as a size, `small`, `medium`, or `large`, in the bootstrap examples). However, `Solidus` still allows you to check out with a variant, regardless of whether or not it has `option_values`. Because of this, none of the typical checkout/fulfillment flow is effected by the auction.
10
+
11
+ Preview Images
12
+ ------------
13
+ Index
14
+ ![index](https://raw.githubusercontent.com/jgujgu/solidus_auction/master/auctions_index.png)
15
+ Show
16
+ ![show](https://raw.githubusercontent.com/jgujgu/solidus_auction/master/auction_show.png)
17
+ Cart. Notice that for auction items, the delete button is nonexistent and the quantity button is disabled.
18
+ ![cart](https://raw.githubusercontent.com/jgujgu/solidus_auction/master/auction_in_cart.png)
19
+ Admin Index
20
+ ![admin_index](https://raw.githubusercontent.com/jgujgu/solidus_auction/master/auctions_admin_index.png)
21
+ Admin Edit
22
+ ![edit](https://raw.githubusercontent.com/jgujgu/solidus_auction/master/auction_edit.png)
23
+
24
+ Installation
25
+ ------------
26
+
27
+ Add solidus_auction to your Gemfile:
28
+
29
+ ```ruby
30
+ gem 'solidus_auction'
31
+ ```
32
+
33
+ Bundle your dependencies and run the installation generator:
34
+
35
+ ```shell
36
+ bundle
37
+ bundle exec rails g solidus_auction:install
38
+ ```
39
+
40
+ Testing
41
+ -------
42
+
43
+ First bundle your dependencies, then run `rake`. `rake` will default to building the dummy app if it does not exist, then it will run specs, and [Rubocop](https://github.com/bbatsov/rubocop) static code analysis. The dummy app can be regenerated by using `rake test_app`.
44
+
45
+ ```shell
46
+ bundle
47
+ bundle exec rake
48
+ ```
49
+
50
+ When testing your applications integration with this extension you may use it's factories.
51
+ Simply add this require statement to your spec_helper:
52
+
53
+ ```ruby
54
+ require 'solidus_auction/factories'
55
+ ```
56
+
57
+ Copyright (c) 2018 [Jeffrey Gu], released under the New BSD License
@@ -0,0 +1,30 @@
1
+ require 'bundler'
2
+
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ begin
6
+ require 'spree/testing_support/extension_rake'
7
+ require 'rubocop/rake_task'
8
+ require 'rspec/core/rake_task'
9
+
10
+ RSpec::Core::RakeTask.new(:spec)
11
+
12
+ RuboCop::RakeTask.new
13
+
14
+ task default: %i(first_run rubocop spec)
15
+ rescue LoadError
16
+ # no rspec available
17
+ end
18
+
19
+ task :first_run do
20
+ if Dir['spec/dummy'].empty?
21
+ Rake::Task[:test_app].invoke
22
+ Dir.chdir('../../')
23
+ end
24
+ end
25
+
26
+ desc 'Generates a dummy app for testing'
27
+ task :test_app do
28
+ ENV['LIB_NAME'] = 'solidus_auction'
29
+ Rake::Task['extension:test_app'].invoke
30
+ end
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,20 @@
1
+ /*
2
+ countdown.js v2.6.0 http://countdownjs.org
3
+ Copyright (c)2006-2014 Stephen M. McKamey.
4
+ Licensed under The MIT License.
5
+ */
6
+ var module,countdown=function(v){function A(a,b){var c=a.getTime();a.setMonth(a.getMonth()+b);return Math.round((a.getTime()-c)/864E5)}function w(a){var b=a.getTime(),c=new Date(b);c.setMonth(a.getMonth()+1);return Math.round((c.getTime()-b)/864E5)}function x(a,b){b=b instanceof Date||null!==b&&isFinite(b)?new Date(+b):new Date;if(!a)return b;var c=+a.value||0;if(c)return b.setTime(b.getTime()+c),b;(c=+a.milliseconds||0)&&b.setMilliseconds(b.getMilliseconds()+c);(c=+a.seconds||0)&&b.setSeconds(b.getSeconds()+
7
+ c);(c=+a.minutes||0)&&b.setMinutes(b.getMinutes()+c);(c=+a.hours||0)&&b.setHours(b.getHours()+c);(c=+a.weeks||0)&&(c*=7);(c+=+a.days||0)&&b.setDate(b.getDate()+c);(c=+a.months||0)&&b.setMonth(b.getMonth()+c);(c=+a.millennia||0)&&(c*=10);(c+=+a.centuries||0)&&(c*=10);(c+=+a.decades||0)&&(c*=10);(c+=+a.years||0)&&b.setFullYear(b.getFullYear()+c);return b}function D(a,b){return y(a)+(1===a?p[b]:q[b])}function n(){}function k(a,b,c,e,l,d){0<=a[c]&&(b+=a[c],delete a[c]);b/=l;if(1>=b+1)return 0;if(0<=a[e]){a[e]=
8
+ +(a[e]+b).toFixed(d);switch(e){case "seconds":if(60!==a.seconds||isNaN(a.minutes))break;a.minutes++;a.seconds=0;case "minutes":if(60!==a.minutes||isNaN(a.hours))break;a.hours++;a.minutes=0;case "hours":if(24!==a.hours||isNaN(a.days))break;a.days++;a.hours=0;case "days":if(7!==a.days||isNaN(a.weeks))break;a.weeks++;a.days=0;case "weeks":if(a.weeks!==w(a.refMonth)/7||isNaN(a.months))break;a.months++;a.weeks=0;case "months":if(12!==a.months||isNaN(a.years))break;a.years++;a.months=0;case "years":if(10!==
9
+ a.years||isNaN(a.decades))break;a.decades++;a.years=0;case "decades":if(10!==a.decades||isNaN(a.centuries))break;a.centuries++;a.decades=0;case "centuries":if(10!==a.centuries||isNaN(a.millennia))break;a.millennia++;a.centuries=0}return 0}return b}function B(a,b,c,e,l,d){var f=new Date;a.start=b=b||f;a.end=c=c||f;a.units=e;a.value=c.getTime()-b.getTime();0>a.value&&(f=c,c=b,b=f);a.refMonth=new Date(b.getFullYear(),b.getMonth(),15,12,0,0);try{a.millennia=0;a.centuries=0;a.decades=0;a.years=c.getFullYear()-
10
+ b.getFullYear();a.months=c.getMonth()-b.getMonth();a.weeks=0;a.days=c.getDate()-b.getDate();a.hours=c.getHours()-b.getHours();a.minutes=c.getMinutes()-b.getMinutes();a.seconds=c.getSeconds()-b.getSeconds();a.milliseconds=c.getMilliseconds()-b.getMilliseconds();var g;0>a.milliseconds?(g=s(-a.milliseconds/1E3),a.seconds-=g,a.milliseconds+=1E3*g):1E3<=a.milliseconds&&(a.seconds+=m(a.milliseconds/1E3),a.milliseconds%=1E3);0>a.seconds?(g=s(-a.seconds/60),a.minutes-=g,a.seconds+=60*g):60<=a.seconds&&(a.minutes+=
11
+ m(a.seconds/60),a.seconds%=60);0>a.minutes?(g=s(-a.minutes/60),a.hours-=g,a.minutes+=60*g):60<=a.minutes&&(a.hours+=m(a.minutes/60),a.minutes%=60);0>a.hours?(g=s(-a.hours/24),a.days-=g,a.hours+=24*g):24<=a.hours&&(a.days+=m(a.hours/24),a.hours%=24);for(;0>a.days;)a.months--,a.days+=A(a.refMonth,1);7<=a.days&&(a.weeks+=m(a.days/7),a.days%=7);0>a.months?(g=s(-a.months/12),a.years-=g,a.months+=12*g):12<=a.months&&(a.years+=m(a.months/12),a.months%=12);10<=a.years&&(a.decades+=m(a.years/10),a.years%=
12
+ 10,10<=a.decades&&(a.centuries+=m(a.decades/10),a.decades%=10,10<=a.centuries&&(a.millennia+=m(a.centuries/10),a.centuries%=10)));b=0;!(e&1024)||b>=l?(a.centuries+=10*a.millennia,delete a.millennia):a.millennia&&b++;!(e&512)||b>=l?(a.decades+=10*a.centuries,delete a.centuries):a.centuries&&b++;!(e&256)||b>=l?(a.years+=10*a.decades,delete a.decades):a.decades&&b++;!(e&128)||b>=l?(a.months+=12*a.years,delete a.years):a.years&&b++;!(e&64)||b>=l?(a.months&&(a.days+=A(a.refMonth,a.months)),delete a.months,
13
+ 7<=a.days&&(a.weeks+=m(a.days/7),a.days%=7)):a.months&&b++;!(e&32)||b>=l?(a.days+=7*a.weeks,delete a.weeks):a.weeks&&b++;!(e&16)||b>=l?(a.hours+=24*a.days,delete a.days):a.days&&b++;!(e&8)||b>=l?(a.minutes+=60*a.hours,delete a.hours):a.hours&&b++;!(e&4)||b>=l?(a.seconds+=60*a.minutes,delete a.minutes):a.minutes&&b++;!(e&2)||b>=l?(a.milliseconds+=1E3*a.seconds,delete a.seconds):a.seconds&&b++;if(!(e&1)||b>=l){var h=k(a,0,"milliseconds","seconds",1E3,d);if(h&&(h=k(a,h,"seconds","minutes",60,d))&&(h=
14
+ k(a,h,"minutes","hours",60,d))&&(h=k(a,h,"hours","days",24,d))&&(h=k(a,h,"days","weeks",7,d))&&(h=k(a,h,"weeks","months",w(a.refMonth)/7,d))){e=h;var n,p=a.refMonth,q=p.getTime(),r=new Date(q);r.setFullYear(p.getFullYear()+1);n=Math.round((r.getTime()-q)/864E5);if(h=k(a,e,"months","years",n/w(a.refMonth),d))if(h=k(a,h,"years","decades",10,d))if(h=k(a,h,"decades","centuries",10,d))if(h=k(a,h,"centuries","millennia",10,d))throw Error("Fractional unit overflow");}}}finally{delete a.refMonth}return a}
15
+ function d(a,b,c,e,d){var f;c=+c||222;e=0<e?e:NaN;d=0<d?20>d?Math.round(d):20:0;var k=null;"function"===typeof a?(f=a,a=null):a instanceof Date||(null!==a&&isFinite(a)?a=new Date(+a):("object"===typeof k&&(k=a),a=null));var g=null;"function"===typeof b?(f=b,b=null):b instanceof Date||(null!==b&&isFinite(b)?b=new Date(+b):("object"===typeof b&&(g=b),b=null));k&&(a=x(k,b));g&&(b=x(g,a));if(!a&&!b)return new n;if(!f)return B(new n,a,b,c,e,d);var k=c&1?1E3/30:c&2?1E3:c&4?6E4:c&8?36E5:c&16?864E5:6048E5,
16
+ h,g=function(){f(B(new n,a,b,c,e,d),h)};g();return h=setInterval(g,k)}var s=Math.ceil,m=Math.floor,p,q,r,t,u,f,y,z;n.prototype.toString=function(a){var b=z(this),c=b.length;if(!c)return a?""+a:u;if(1===c)return b[0];a=r+b.pop();return b.join(t)+a};n.prototype.toHTML=function(a,b){a=a||"span";var c=z(this),e=c.length;if(!e)return(b=b||u)?"\x3c"+a+"\x3e"+b+"\x3c/"+a+"\x3e":b;for(var d=0;d<e;d++)c[d]="\x3c"+a+"\x3e"+c[d]+"\x3c/"+a+"\x3e";if(1===e)return c[0];e=r+c.pop();return c.join(t)+e};n.prototype.addTo=
17
+ function(a){return x(this,a)};z=function(a){var b=[],c=a.millennia;c&&b.push(f(c,10));(c=a.centuries)&&b.push(f(c,9));(c=a.decades)&&b.push(f(c,8));(c=a.years)&&b.push(f(c,7));(c=a.months)&&b.push(f(c,6));(c=a.weeks)&&b.push(f(c,5));(c=a.days)&&b.push(f(c,4));(c=a.hours)&&b.push(f(c,3));(c=a.minutes)&&b.push(f(c,2));(c=a.seconds)&&b.push(f(c,1));(c=a.milliseconds)&&b.push(f(c,0));return b};d.MILLISECONDS=1;d.SECONDS=2;d.MINUTES=4;d.HOURS=8;d.DAYS=16;d.WEEKS=32;d.MONTHS=64;d.YEARS=128;d.DECADES=256;
18
+ d.CENTURIES=512;d.MILLENNIA=1024;d.DEFAULTS=222;d.ALL=2047;var E=d.setFormat=function(a){if(a){if("singular"in a||"plural"in a){var b=a.singular||[];b.split&&(b=b.split("|"));var c=a.plural||[];c.split&&(c=c.split("|"));for(var d=0;10>=d;d++)p[d]=b[d]||p[d],q[d]=c[d]||q[d]}"string"===typeof a.last&&(r=a.last);"string"===typeof a.delim&&(t=a.delim);"string"===typeof a.empty&&(u=a.empty);"function"===typeof a.formatNumber&&(y=a.formatNumber);"function"===typeof a.formatter&&(f=a.formatter)}},C=d.resetFormat=
19
+ function(){p=" millisecond; second; minute; hour; day; week; month; year; decade; century; millennium".split(";");q=" milliseconds; seconds; minutes; hours; days; weeks; months; years; decades; centuries; millennia".split(";");r=" and ";t=", ";u="";y=function(a){return a};f=D};d.setLabels=function(a,b,c,d,f,k,m){E({singular:a,plural:b,last:c,delim:d,empty:f,formatNumber:k,formatter:m})};d.resetLabels=C;C();v&&v.exports?v.exports=d:"function"===typeof window.define&&"undefined"!==typeof window.define.amd&&
20
+ window.define("countdown",[],function(){return d});return d}(module);
@@ -0,0 +1 @@
1
+ (function(){var t=this;(function(){(function(){var t=[].slice;this.LocalTime={config:{},run:function(){return this.getController().processElements()},process:function(){var e,n,r,a;for(n=1<=arguments.length?t.call(arguments,0):[],r=0,a=n.length;r<a;r++)e=n[r],this.getController().processElement(e);return n.length},getController:function(){return null!=this.controller?this.controller:this.controller=new e.Controller}}}).call(this)}).call(t);var e=t.LocalTime;(function(){(function(){e.config.i18n={en:{date:{dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],abbrDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],abbrMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],yesterday:"yesterday",today:"today",tomorrow:"tomorrow",on:"on {date}",formats:{"default":"%b %e, %Y",thisYear:"%b %e"}},time:{am:"am",pm:"pm",singular:"a {time}",singularAn:"an {time}",elapsed:"{time} ago",second:"second",seconds:"seconds",minute:"minute",minutes:"minutes",hour:"hour",hours:"hours",formats:{"default":"%l:%M%P"}},datetime:{at:"{date} at {time}",formats:{"default":"%B %e, %Y at %l:%M%P %Z"}}}}}).call(this),function(){e.config.locale="en",e.config.defaultLocale="en"}.call(this),function(){e.config.timerInterval=6e4}.call(this),function(){var t,n,r;r=!isNaN(Date.parse("2011-01-01T12:00:00-05:00")),e.parseDate=function(t){return t=t.toString(),r||(t=n(t)),new Date(Date.parse(t))},t=/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(Z|[-+]?[\d:]+)$/,n=function(e){var n,r,a,i,o,s,u,c,l;if(a=e.match(t))return a[0],c=a[1],o=a[2],n=a[3],r=a[4],i=a[5],u=a[6],l=a[7],"Z"!==l&&(s=l.replace(":","")),c+"/"+o+"/"+n+" "+r+":"+i+":"+u+" GMT"+[s]}}.call(this),function(){e.elementMatchesSelector=function(){var t,e,n,r,a,i;return t=document.documentElement,e=null!=(n=null!=(r=null!=(a=null!=(i=t.matches)?i:t.matchesSelector)?a:t.webkitMatchesSelector)?r:t.mozMatchesSelector)?n:t.msMatchesSelector,function(t,n){if((null!=t?t.nodeType:void 0)===Node.ELEMENT_NODE)return e.call(t,n)}}()}.call(this),function(){var t,n,r;t=e.config,r=t.i18n,e.getI18nValue=function(a,i){var o,s;return null==a&&(a=""),o=(null!=i?i:{locale:t.locale}).locale,s=n(r[o],a),null!=s?s:o!==t.defaultLocale?e.getI18nValue(a,{locale:t.defaultLocale}):void 0},e.translate=function(t,n,r){var a,i,o;null==n&&(n={}),o=e.getI18nValue(t,r);for(a in n)i=n[a],o=o.replace("{"+a+"}",i);return o},n=function(t,e){var n,r,a,i,o;for(o=t,i=e.split("."),n=0,a=i.length;n<a;n++){if(r=i[n],null==o[r])return null;o=o[r]}return o}}.call(this),function(){var t,n,r,a,i;t=e.getI18nValue,i=e.translate,e.strftime=a=function(e,o){var s,u,c,l,d,h,f;return u=e.getDay(),s=e.getDate(),d=e.getMonth(),f=e.getFullYear(),c=e.getHours(),l=e.getMinutes(),h=e.getSeconds(),o.replace(/%([%aAbBcdeHIlmMpPSwyYZ])/g,function(o){switch(o[0],o[1]){case"%":return"%";case"a":return t("date.abbrDayNames")[u];case"A":return t("date.dayNames")[u];case"b":return t("date.abbrMonthNames")[d];case"B":return t("date.monthNames")[d];case"c":return e.toString();case"d":return n(s);case"e":return s;case"H":return n(c);case"I":return n(a(e,"%l"));case"l":return 0===c||12===c?12:(c+12)%12;case"m":return n(d+1);case"M":return n(l);case"p":return i("time."+(c>11?"pm":"am")).toUpperCase();case"P":return i("time."+(c>11?"pm":"am"));case"S":return n(h);case"w":return u;case"y":return n(f%100);case"Y":return f;case"Z":return r(e)}})},n=function(t){return("0"+t).slice(-2)},r=function(t){var e,n,r,a,i;return i=t.toString(),(e=null!=(n=i.match(/\(([\w\s]+)\)$/))?n[1]:void 0)?/\s/.test(e)?e.match(/\b(\w)/g).join(""):e:(e=null!=(r=i.match(/(\w{3,4})\s\d{4}$/))?r[1]:void 0)?e:(e=null!=(a=i.match(/(UTC[\+\-]\d+)/))?a[1]:void 0)?e:""}}.call(this),function(){e.CalendarDate=function(){function t(t,e,n){this.date=new Date(Date.UTC(t,e-1)),this.date.setUTCDate(n),this.year=this.date.getUTCFullYear(),this.month=this.date.getUTCMonth()+1,this.day=this.date.getUTCDate(),this.value=this.date.getTime()}return t.fromDate=function(t){return new this(t.getFullYear(),t.getMonth()+1,t.getDate())},t.today=function(){return this.fromDate(new Date)},t.prototype.equals=function(t){return(null!=t?t.value:void 0)===this.value},t.prototype.is=function(t){return this.equals(t)},t.prototype.isToday=function(){return this.is(this.constructor.today())},t.prototype.occursOnSameYearAs=function(t){return this.year===(null!=t?t.year:void 0)},t.prototype.occursThisYear=function(){return this.occursOnSameYearAs(this.constructor.today())},t.prototype.daysSince=function(t){if(t)return(this.date-t.date)/864e5},t.prototype.daysPassed=function(){return this.constructor.today().daysSince(this)},t}()}.call(this),function(){var t,n,r;n=e.strftime,r=e.translate,t=e.getI18nValue,e.RelativeTime=function(){function a(t){this.date=t,this.calendarDate=e.CalendarDate.fromDate(this.date)}return a.prototype.toString=function(){var t,e;return(e=this.toTimeElapsedString())?r("time.elapsed",{time:e}):(t=this.toWeekdayString())?(e=this.toTimeString(),r("datetime.at",{date:t,time:e})):r("date.on",{date:this.toDateString()})},a.prototype.toTimeOrDateString=function(){return this.calendarDate.isToday()?this.toTimeString():this.toDateString()},a.prototype.toTimeElapsedString=function(){var t,e,n,a,i;return n=(new Date).getTime()-this.date.getTime(),a=Math.round(n/1e3),e=Math.round(a/60),t=Math.round(e/60),n<0?null:a<10?(i=r("time.second"),r("time.singular",{time:i})):a<45?a+" "+r("time.seconds"):a<90?(i=r("time.minute"),r("time.singular",{time:i})):e<45?e+" "+r("time.minutes"):e<90?(i=r("time.hour"),r("time.singularAn",{time:i})):t<24?t+" "+r("time.hours"):""},a.prototype.toWeekdayString=function(){switch(this.calendarDate.daysPassed()){case 0:return r("date.today");case 1:return r("date.yesterday");case-1:return r("date.tomorrow");case 2:case 3:case 4:case 5:case 6:return n(this.date,"%A");default:return""}},a.prototype.toDateString=function(){var e;return e=t(this.calendarDate.occursThisYear()?"date.formats.thisYear":"date.formats.default"),n(this.date,e)},a.prototype.toTimeString=function(){return n(this.date,t("time.formats.default"))},a}()}.call(this),function(){var t,n=function(t,e){return function(){return t.apply(e,arguments)}};t=e.elementMatchesSelector,e.PageObserver=function(){function e(t,e){this.selector=t,this.callback=e,this.processInsertion=n(this.processInsertion,this),this.processMutations=n(this.processMutations,this)}return e.prototype.start=function(){if(!this.started)return this.observeWithMutationObserver()||this.observeWithMutationEvent(),this.started=!0},e.prototype.observeWithMutationObserver=function(){var t;if("undefined"!=typeof MutationObserver&&null!==MutationObserver)return t=new MutationObserver(this.processMutations),t.observe(document.documentElement,{childList:!0,subtree:!0}),!0},e.prototype.observeWithMutationEvent=function(){return addEventListener("DOMNodeInserted",this.processInsertion,!1),!0},e.prototype.findSignificantElements=function(e){var n;return n=[],(null!=e?e.nodeType:void 0)===Node.ELEMENT_NODE&&(t(e,this.selector)&&n.push(e),n.push.apply(n,e.querySelectorAll(this.selector))),n},e.prototype.processMutations=function(t){var e,n,r,a,i,o,s,u;for(e=[],n=0,a=t.length;n<a;n++)switch(o=t[n],o.type){case"childList":for(u=o.addedNodes,r=0,i=u.length;r<i;r++)s=u[r],e.push.apply(e,this.findSignificantElements(s))}return this.notify(e)},e.prototype.processInsertion=function(t){var e;return e=this.findSignificantElements(t.target),this.notify(e)},e.prototype.notify=function(t){if(null!=t?t.length:void 0)return"function"==typeof this.callback?this.callback(t):void 0},e}()}.call(this),function(){var t,n,r,a,i=function(t,e){return function(){return t.apply(e,arguments)}};r=e.parseDate,a=e.strftime,n=e.getI18nValue,t=e.config,e.Controller=function(){function o(){this.processElements=i(this.processElements,this),this.pageObserver=new e.PageObserver(s,this.processElements)}var s,u,c;return s="time[data-local]:not([data-localized])",o.prototype.start=function(){if(!this.started)return this.processElements(),this.startTimer(),this.pageObserver.start(),this.started=!0},o.prototype.startTimer=function(){var e;if(e=t.timerInterval)return null!=this.timer?this.timer:this.timer=setInterval(this.processElements,e)},o.prototype.processElements=function(t){var e,n,r;for(null==t&&(t=document.querySelectorAll(s)),n=0,r=t.length;n<r;n++)e=t[n],this.processElement(e);return t.length},o.prototype.processElement=function(t){var e,i,o,s,l;if(e=t.getAttribute("datetime"),i=t.getAttribute("data-format"),o=t.getAttribute("data-local"),s=r(e),!isNaN(s))return t.hasAttribute("title")||(l=a(s,n("datetime.formats.default")),t.setAttribute("title",l)),t.textContent=function(){switch(o){case"time":return u(t),a(s,i);case"date":return u(t),c(s).toDateString();case"time-ago":return c(s).toString();case"time-or-date":return c(s).toTimeOrDateString();case"weekday":return c(s).toWeekdayString();case"weekday-or-date":return c(s).toWeekdayString()||c(s).toDateString()}}()},u=function(t){return t.setAttribute("data-localized","")},c=function(t){return new e.RelativeTime(t)},o}()}.call(this),function(){var t,n,r,a;a=!1,t=function(){return document.attachEvent?"complete"===document.readyState:"loading"!==document.readyState},n=function(t){var e;return null!=(e="function"==typeof requestAnimationFrame?requestAnimationFrame(t):void 0)?e:setTimeout(t,17)},r=function(){var t;return t=e.getController(),t.start()},e.start=function(){if(!a)return a=!0,"undefined"!=typeof MutationObserver&&null!==MutationObserver||t()?r():n(r)},window.LocalTime===e&&e.start()}.call(this)}).call(this),"object"==typeof module&&module.exports?module.exports=e:"function"==typeof define&&define.amd&&define(e)}).call(this);
@@ -0,0 +1,50 @@
1
+ Spree.ready(function () {
2
+ 'use strict';
3
+
4
+ function formatProduct(product) {
5
+ return Select2.util.escapeMarkup(product.name);
6
+ }
7
+
8
+ if ($('#auction_product_id').length > 0) {
9
+ $('#auction_product_id').select2({
10
+ placeholder: Spree.translations.product_placeholder,
11
+ multiple: false,
12
+ initSelection: function (element, callback) {
13
+ return Spree.ajax({
14
+ url: Spree.routes.admin_product_search,
15
+ data: { ids: element.val() },
16
+ type: 'get',
17
+ success: function(data) {
18
+ return callback(data.products[0]);
19
+ }
20
+ });
21
+ },
22
+
23
+ ajax: {
24
+ url: Spree.routes.admin_product_search,
25
+ datatype: 'json',
26
+ params: { "headers": { "X-Spree-Token": Spree.api_key } },
27
+ data: function (term, page) {
28
+ return {
29
+ q: {
30
+ name_cont: term,
31
+ variants_including_master_sku_start: term,
32
+ m: 'or'
33
+ },
34
+ token: Spree.api_key,
35
+ page: page
36
+ };
37
+ },
38
+ results: function (data, page) {
39
+ var products = data.products ? data.products : [];
40
+ return {
41
+ results: products,
42
+ more: (data.current_page * data.per_page) < data.total_count
43
+ };
44
+ }
45
+ },
46
+ formatResult: formatProduct,
47
+ formatSelection: formatProduct
48
+ });
49
+ }
50
+ });
@@ -0,0 +1,7 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/backend/all.js'
3
+
4
+ //= require spree/backend/product_autocomplete
5
+ //= require countdown
6
+ //= require spree/ends_in
7
+ //= require local-time
@@ -0,0 +1,31 @@
1
+ $(document).ready(function() {
2
+ setInterval(updateTimes, 1000);
3
+ });
4
+
5
+ function updateTimes() {
6
+ var timeRemainings = $(".ends-in")
7
+ if (timeRemainings.length > 0) {
8
+ $.each(timeRemainings, updateTime);
9
+ }
10
+ }
11
+
12
+ function updateTime(_, element) {
13
+ var $element = $(element);
14
+ var currentDatetime = new Date();
15
+ var auctionEndDatetime = $element.data("auction-end-datetime");
16
+ if (currentDatetime > auctionEndDatetime) {
17
+ var pretext = $element.siblings()[0];
18
+ pretext.addClass("green");
19
+ pretext.innerHTML = "Complete";
20
+ $element.remove();
21
+ } else {
22
+ var countdownString = countdown(
23
+ null,
24
+ auctionEndDatetime,
25
+ countdown.DAYS|countdown.HOURS|countdown.MINUTES|countdown.SECONDS,
26
+ 2
27
+ ).toString();
28
+ }
29
+ element.innerHTML = countdownString;
30
+ }
31
+
@@ -0,0 +1,8 @@
1
+ // Placeholder manifest file.
2
+ // the installer will append this file to the app vendored assets here: vendor/assets/javascripts/spree/frontend/all.js'
3
+
4
+ //= require local-time
5
+ //= require countdown
6
+ //= require spree/ends_in
7
+ //= require spree/frontend/starts_in
8
+ //= require spree/frontend/votes
@@ -0,0 +1,32 @@
1
+ $(document).ready(function() {
2
+ setInterval(updateStartTimes, 1000);
3
+ });
4
+
5
+ function updateStartTimes() {
6
+ var timeRemainings = $(".starts-in")
7
+ if (timeRemainings.length > 0) {
8
+ $.each(timeRemainings, updateStartTime);
9
+ }
10
+ }
11
+
12
+ function updateStartTime(_, element) {
13
+ var $element = $(element);
14
+ var currentDatetime = new Date();
15
+ var dateTime = $element.data("auction-starting-datetime");
16
+ if (currentDatetime > dateTime) {
17
+ $element.removeClass("starts-in");
18
+ $element.removeClass("green");
19
+ $element.addClass("ends-in");
20
+ $element.addClass("red");
21
+ var pretext = $element.siblings()[0];
22
+ pretext.innerHTML = "Ends in";
23
+ } else {
24
+ var countdownString = countdown(
25
+ dateTime,
26
+ null,
27
+ countdown.DAYS|countdown.HOURS|countdown.MINUTES|countdown.SECONDS,
28
+ 2
29
+ ).toString();
30
+ }
31
+ element.innerHTML = countdownString;
32
+ }
@@ -0,0 +1,83 @@
1
+ var root;
2
+
3
+ Spree.ready(function () {
4
+ $(document).ready(function() {
5
+ root = getRootUrl();
6
+ setInterval(updateVotes, 60000);
7
+ var votes = $(".votes")
8
+ votes.click(changeVote)
9
+ });
10
+ })
11
+
12
+ function updateVotes() {
13
+ var votes = $(".votes")
14
+ if (votes.length > 0) {
15
+ $.each(votes, updateVote);
16
+ }
17
+ }
18
+
19
+ function updateVote(_, element) {
20
+ var $element = $(element);
21
+ var auctionId = $element.data('auction-id');
22
+ var params = { auction_id: auctionId };
23
+
24
+ Spree.ajax({
25
+ url: root + "/vote_count/",
26
+ data: params,
27
+ success: function(data) {
28
+ $element.children()[0].innerHTML = data["votes"];
29
+ }
30
+ });
31
+ }
32
+
33
+ function changeVote(e) {
34
+ e.preventDefault();
35
+ var $this = $(this);
36
+ var userId = $this.data('user-id');
37
+ if (userId) {
38
+ var auctionId = $this.data('auction-id');
39
+ var votedFor = $this.data('voted-for');
40
+ var params = {auction_id: auctionId, user_id: userId };
41
+ if (votedFor) {
42
+ Spree.ajax({
43
+ url: root + "/vote_down/",
44
+ data: params,
45
+ success: setVoteWidget.bind(this)
46
+ });
47
+ } else {
48
+ Spree.ajax({
49
+ url: root + "/vote_up/",
50
+ data: params,
51
+ success: setVoteWidget.bind(this)
52
+ });
53
+ }
54
+ }
55
+ }
56
+
57
+ function setVoteWidget(data) {
58
+ var votedFor = data["voted_for"];
59
+ var $this = $(this);
60
+ if (votedFor == 1) {
61
+ setData($this, 'voted-for', true);
62
+ $this.addClass("green");
63
+ $this.children()[0].innerHTML = data["votes"];
64
+ } else {
65
+ setData($this, 'voted-for', false);
66
+ $this.removeClass("green");
67
+ $this.children()[0].innerHTML = data["votes"];
68
+ }
69
+ }
70
+
71
+ function setData(element, key, data) {
72
+ element.data(key, data);
73
+ element.attr('data-' + key, data);
74
+ }
75
+
76
+ function getRootUrl() {
77
+ var defaultPorts = {"http:":80,"https:":443};
78
+
79
+ return window.location.protocol + "//" + window.location.hostname
80
+ + (((window.location.port)
81
+ && (window.location.port != defaultPorts[window.location.protocol]))
82
+ ? (":"+window.location.port) : "");
83
+ }
@@ -0,0 +1,16 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
5
+
6
+ .red {
7
+ color: #e45353;
8
+ }
9
+
10
+ .green {
11
+ color: #8dba53;
12
+ }
13
+
14
+ .bold {
15
+ font-weight: bold;
16
+ }
@@ -0,0 +1,24 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
5
+
6
+ .add-to-cart input[type="number"] {
7
+ width: 80px !important;
8
+ }
9
+
10
+ .red {
11
+ color: #e45353;
12
+ }
13
+
14
+ .green {
15
+ color: #8dba53;
16
+ }
17
+
18
+ .bold {
19
+ font-weight: bold;
20
+ }
21
+
22
+ .votes {
23
+ cursor: pointer;
24
+ }
@@ -0,0 +1,16 @@
1
+ class Spree::Admin::AuctionSettingsController < Spree::Admin::BaseController
2
+ def edit
3
+ @config = Spree::AuctionSettings::Config
4
+ end
5
+
6
+ def update
7
+ config = Spree::AuctionSettings::Config
8
+
9
+ params.each do |name, value|
10
+ next unless config.has_preference? name
11
+ config[name] = value
12
+ end
13
+
14
+ redirect_to edit_admin_auction_settings_path
15
+ end
16
+ end
@@ -0,0 +1,46 @@
1
+ class Spree::Admin::AuctionsController < Spree::Admin::ResourceController
2
+ create.before :create_before
3
+ helper_method :disable_on_start
4
+ helper_method :disable_on_complete
5
+ helper Spree::Helpers::LocalTimeHelper
6
+
7
+ def index
8
+ session[:return_to] = request.url
9
+ @collection = @collection.current_end_datetime_descending
10
+ respond_with(@collection)
11
+ end
12
+
13
+ def show
14
+ redirect_to action: :edit
15
+ end
16
+
17
+ private
18
+
19
+ def disable_on_start(auction_started, enabled_options)
20
+ if auction_started
21
+ { readonly: true, disabled: true }.merge(enabled_options)
22
+ else
23
+ enabled_options
24
+ end
25
+ end
26
+
27
+ def disable_on_complete(auction_complete, enabled_options)
28
+ if auction_complete
29
+ { readonly: true, disabled: true }.merge(enabled_options)
30
+ else
31
+ enabled_options
32
+ end
33
+ end
34
+
35
+ def create_before
36
+ @auction.creator = spree_current_user if spree_user_signed_in?
37
+ end
38
+
39
+ def permitted_auction_attributes
40
+ %i{id title description starting_datetime planned_end_datetime starting_price reserve_price bid_increment time_increment countdown product_id}
41
+ end
42
+
43
+ def permitted_resource_params
44
+ params.require(:auction).permit(permitted_auction_attributes)
45
+ end
46
+ end