caboose-store 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (143) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/caboose/main.js +8 -0
  3. data/app/assets/javascripts/caboose_store/admin.js +0 -19
  4. data/app/assets/javascripts/caboose_store/admin_products.js +3 -4
  5. data/app/assets/javascripts/caboose_store/application.js +6 -5
  6. data/app/assets/javascripts/caboose_store/cart.js.bak +258 -0
  7. data/app/assets/javascripts/caboose_store/checkout.js +151 -0
  8. data/app/assets/javascripts/caboose_store/config.js +83 -0
  9. data/app/assets/javascripts/caboose_store/jquery-ui-multisortable.js +254 -0
  10. data/app/assets/javascripts/caboose_store/jquery-ui.js +3572 -0
  11. data/app/assets/javascripts/caboose_store/main.js +20 -0
  12. data/app/assets/javascripts/caboose_store/modules/cart.js +167 -0
  13. data/app/assets/javascripts/caboose_store/modules/checkout.js +313 -0
  14. data/app/assets/javascripts/caboose_store/modules/product.js +282 -0
  15. data/app/assets/stylesheets/caboose_store/admin.css +3 -3
  16. data/app/assets/stylesheets/caboose_store/application.css +2 -2
  17. data/app/assets/stylesheets/caboose_store/modal.css +1 -0
  18. data/app/assets/templates/caboose_store/cart/add_to_cart.jst.ejs +7 -0
  19. data/app/assets/templates/caboose_store/cart/line_items.jst.ejs +41 -0
  20. data/app/assets/templates/caboose_store/checkout/address.jst.ejs +53 -0
  21. data/app/assets/templates/caboose_store/checkout/forms/guest.jst.ejs +8 -0
  22. data/app/assets/templates/caboose_store/checkout/forms/register.jst.ejs +11 -0
  23. data/app/assets/templates/caboose_store/checkout/forms/signin.jst.ejs +7 -0
  24. data/app/assets/templates/caboose_store/checkout/line_items.jst.ejs +32 -0
  25. data/app/assets/templates/caboose_store/checkout/login.jst.ejs +21 -0
  26. data/app/assets/templates/caboose_store/checkout/payment.jst.ejs +5 -0
  27. data/app/assets/templates/caboose_store/checkout/shipping.jst.ejs +18 -0
  28. data/app/assets/templates/caboose_store/product/images.jst.ejs +8 -0
  29. data/app/assets/templates/caboose_store/product/options.jst.ejs +19 -0
  30. data/app/controllers/caboose_store/application_controller.rb +1 -11
  31. data/app/controllers/caboose_store/cart_controller.rb +36 -44
  32. data/app/controllers/caboose_store/cart_controller.rb.bak +169 -0
  33. data/app/controllers/caboose_store/categories_controller.rb +72 -92
  34. data/app/controllers/caboose_store/checkout_controller.rb +231 -151
  35. data/app/controllers/caboose_store/orders_controller.rb +235 -95
  36. data/app/controllers/caboose_store/product_images_controller.rb +1 -1
  37. data/app/controllers/caboose_store/products_controller.rb +275 -84
  38. data/app/controllers/caboose_store/reviews_controller.rb +1 -1
  39. data/app/controllers/caboose_store/variants_controller.rb +86 -20
  40. data/app/controllers/caboose_store/vendors_controller.rb +73 -0
  41. data/app/helpers/caboose_store/application_helper.rb +3 -41
  42. data/app/helpers/caboose_store/cart_helper.rb +0 -24
  43. data/app/helpers/caboose_store/categories_helper.rb +69 -25
  44. data/app/helpers/caboose_store/checkout_helper.rb +31 -0
  45. data/app/helpers/caboose_store/products_helper.rb +4 -80
  46. data/app/mailers/caboose_store/orders_mailer.rb +6 -13
  47. data/app/models/caboose_store/address.rb +5 -9
  48. data/app/models/caboose_store/caboose_store_plugin.rb +18 -7
  49. data/app/models/caboose_store/category.rb +66 -41
  50. data/app/models/caboose_store/category_membership.rb +1 -2
  51. data/app/models/caboose_store/customization_membership.rb +10 -0
  52. data/app/models/caboose_store/discount.rb +4 -2
  53. data/app/models/caboose_store/line_item.rb +77 -0
  54. data/app/models/caboose_store/message.rb +3 -5
  55. data/app/models/caboose_store/order.rb +153 -63
  56. data/app/models/caboose_store/order_discount.rb +1 -2
  57. data/app/models/caboose_store/order_pdf.rb +2 -4
  58. data/app/models/caboose_store/payment_processors/authorizenet.rb +20 -2
  59. data/app/models/caboose_store/payment_processors/base.rb +0 -2
  60. data/app/models/caboose_store/payment_processors/payscape.rb +91 -1
  61. data/app/models/caboose_store/product.rb +86 -30
  62. data/app/models/caboose_store/product_image.rb +50 -15
  63. data/app/models/caboose_store/product_image_variant.rb +3 -3
  64. data/app/models/caboose_store/review.rb +8 -8
  65. data/app/models/caboose_store/schema.rb +174 -119
  66. data/app/models/caboose_store/search_filter.rb +110 -115
  67. data/app/models/caboose_store/shipping_calculator.rb +51 -49
  68. data/app/models/caboose_store/tax_calculator.rb +2 -6
  69. data/app/models/caboose_store/tax_line.rb +1 -4
  70. data/app/models/caboose_store/variant.rb +77 -21
  71. data/app/models/caboose_store/vendor.rb +17 -2
  72. data/app/views/caboose_store/cart/index.html.erb +3 -18
  73. data/app/views/caboose_store/categories/admin_edit.html.erb +64 -67
  74. data/app/views/caboose_store/categories/admin_index.html.erb +7 -9
  75. data/app/views/caboose_store/categories/admin_new.html.erb +56 -39
  76. data/app/views/caboose_store/checkout/_address_form.html.erb +111 -0
  77. data/app/views/caboose_store/checkout/_billing_form.html.erb +47 -0
  78. data/app/views/caboose_store/checkout/_cart.html.erb +52 -0
  79. data/app/views/caboose_store/checkout/_order_discount.html.erb +40 -0
  80. data/app/views/caboose_store/checkout/_shipping_address.html.erb +10 -0
  81. data/app/views/caboose_store/checkout/_shipping_method.html.erb +2 -0
  82. data/app/views/caboose_store/checkout/_shipping_method_form.html.erb +21 -0
  83. data/app/views/caboose_store/checkout/billing.html.erb +4 -161
  84. data/app/views/caboose_store/checkout/discount.html.erb +5 -160
  85. data/app/views/caboose_store/checkout/empty.html.erb +2 -0
  86. data/app/views/caboose_store/checkout/error.html.erb +2 -0
  87. data/app/views/caboose_store/checkout/index.html.erb +30 -100
  88. data/app/views/caboose_store/checkout/login.html.erb +2 -0
  89. data/app/views/caboose_store/checkout/payment.html.erb +79 -0
  90. data/app/views/caboose_store/checkout/relay.html.erb +12 -0
  91. data/app/views/caboose_store/checkout/relay_postMessage.html.erb +19 -0
  92. data/app/views/caboose_store/checkout/shipping.html.erb +8 -83
  93. data/app/views/caboose_store/checkout/step_one.html.erb +15 -0
  94. data/app/views/caboose_store/checkout/step_two.html.erb +15 -0
  95. data/app/views/caboose_store/checkout/thanks.html.erb +5 -0
  96. data/app/views/caboose_store/layouts/_footer.html.erb +1 -1
  97. data/app/views/caboose_store/orders/admin_edit.html.erb +101 -7
  98. data/app/views/caboose_store/orders/admin_index.html.erb +8 -8
  99. data/app/views/caboose_store/orders_mailer/customer_new_order.html.erb +0 -46
  100. data/app/views/caboose_store/orders_mailer/customer_status_updated.html.erb +0 -48
  101. data/app/views/caboose_store/orders_mailer/fulfillment_new_order.html.erb +0 -42
  102. data/app/views/caboose_store/orders_mailer/shipping_order_ready.html.erb +0 -45
  103. data/app/views/caboose_store/products/_admin_header.html.erb +7 -6
  104. data/app/views/caboose_store/products/_sort_options.html.erb +19 -0
  105. data/app/views/caboose_store/products/admin_add_upcs.html.erb +58 -0
  106. data/app/views/caboose_store/products/admin_edit_categories.html.erb +1 -1
  107. data/app/views/caboose_store/products/admin_edit_description.html.erb +2 -5
  108. data/app/views/caboose_store/products/admin_edit_general.html.erb +58 -1
  109. data/app/views/caboose_store/products/admin_edit_images.html.erb +3 -1
  110. data/app/views/caboose_store/products/admin_edit_variants.html.erb +13 -2
  111. data/app/views/caboose_store/products/admin_edit_variants_single.html.erb +14 -14
  112. data/app/views/caboose_store/products/admin_group_variants.html.erb +433 -0
  113. data/app/views/caboose_store/products/admin_index.html.erb +87 -39
  114. data/app/views/caboose_store/products/admin_sort.html copy.erb +155 -0
  115. data/app/views/caboose_store/products/admin_sort.html.erb +254 -0
  116. data/app/views/caboose_store/products/details.html.erb +1 -2
  117. data/app/views/caboose_store/variants/admin_edit.html.erb +18 -16
  118. data/app/views/caboose_store/variants/admin_group.html.erb +184 -0
  119. data/app/views/caboose_store/vendors/admin_edit.html.erb +24 -0
  120. data/app/views/caboose_store/vendors/admin_index.html.erb +30 -0
  121. data/app/views/caboose_store/vendors/admin_new.html.erb +34 -0
  122. data/config/routes.rb +65 -27
  123. data/lib/caboose-store/caboose_store_helper.rb +29 -30
  124. data/lib/caboose-store/engine.rb +73 -28
  125. data/lib/caboose-store/version.rb +1 -1
  126. data/lib/caboose-store.rb +16 -7
  127. data/lib/tasks/caboose-store.rake +0 -2
  128. metadata +54 -17
  129. data/app/assets/javascripts/caboose_store/modal.js +0 -52
  130. data/app/assets/javascripts/caboose_store/modal_integration.js +0 -25
  131. data/app/assets/javascripts/caboose_store/model.form.page.js +0 -30
  132. data/app/assets/javascripts/caboose_store/model.form.user.js +0 -36
  133. data/app/assets/javascripts/caboose_store/payment_processors/authorizenet.js +0 -21
  134. data/app/assets/javascripts/caboose_store/payment_processors/base.js +0 -21
  135. data/app/assets/javascripts/caboose_store/payment_processors/payscape.js +0 -21
  136. data/app/assets/javascripts/caboose_store/shortcut.js +0 -11
  137. data/app/assets/javascripts/caboose_store/station.js +0 -60
  138. data/app/models/caboose_store/order_line_item.rb +0 -13
  139. data/app/models/caboose_store/states.rb +0 -60
  140. data/app/views/caboose_store/application/_category_thumb.html.erb +0 -6
  141. data/app/views/caboose_store/application/_product_thumb.html.erb +0 -13
  142. data/app/views/caboose_store/checkout/quantity_box.html.erb +0 -39
  143. data/app/views/caboose_store/checkout/thank_you.html.erb +0 -36
@@ -0,0 +1,282 @@
1
+ //
2
+ // Product
3
+ //
4
+
5
+ Caboose.Store.Modules.Product = (function() {
6
+ var self = {
7
+ templates: {
8
+ images: JST['caboose_store/product/images'],
9
+ options: JST['caboose_store/product/options']
10
+ }
11
+ };
12
+
13
+ //
14
+ // Initialize
15
+ //
16
+
17
+ self.initialize = function() {
18
+ self.$product = $('#product');
19
+ self.$price = self.$product.find('#product-price');
20
+ if (!self.$product.length) return false;
21
+
22
+ $.get('/products/' + self.$product.data('id') + '/info', function(response) {
23
+ self.product = response.product;
24
+ self.render();
25
+ self.bindEvents();
26
+ self.setVariant(self.getInitialVariant());
27
+ self.setOptionsFromVariant(self.variant);
28
+ });
29
+ };
30
+
31
+ //
32
+ // Render
33
+ //
34
+
35
+ self.render = function() {
36
+ var renderFunctions = [];
37
+ renderFunctions.push(self.renderImages);
38
+ renderFunctions.push(self.renderOptions);
39
+
40
+ _.each(renderFunctions, function(renderFunction, index) {
41
+ var finished = index == (renderFunctions.length - 1);
42
+
43
+ renderFunction(function() {
44
+ if (finished) self.$product.removeClass('loading');
45
+ });
46
+ });
47
+ };
48
+
49
+ self.renderImages = function(callback) {
50
+ self.$images = $('#product-images', self.$product);
51
+ if (!self.$images.length) return false;
52
+ self.$images.empty().html(self.templates.images({ images: self.product.images }));
53
+ if (callback) callback();
54
+ };
55
+
56
+ self.renderOptions = function(callback) {
57
+ self.$options = $('#product-options', self.$options);
58
+ if (!self.$options.length) return false;
59
+ self.$options.empty().html(self.templates.options({ options: self.getOptionsWithAllValues() }));
60
+ if (callback) callback();
61
+ };
62
+
63
+ //
64
+ // Out of Stock
65
+ //
66
+
67
+ self.outOfStock = function() {
68
+ self.$product.find('#add-to-cart').after($('<p/>').addClass('message error').text('Out of Stock')).remove();
69
+ };
70
+
71
+ //
72
+ // Events
73
+ //
74
+
75
+ self.bindEvents = function() {
76
+ self.$images.find('ul > li > figure').on('click', self.thumbClickHandler);
77
+ self.$images.children('figure').on('click', self.imageClickHandler);
78
+ self.$options.find('ul').on('click', 'li', self.optionClickHandler);
79
+ };
80
+
81
+ self.thumbClickHandler = function(event) {
82
+ self.$images.children('figure').css('background-image', 'url(' + $(event.target).data('url-large') + ')');
83
+ };
84
+
85
+ self.imageClickHandler = function(event) {
86
+ window.location = $(event.target).css('background-image').match(/^url\("(.*)"\)$/)[1];
87
+ };
88
+
89
+ self.optionClickHandler = function(event) {
90
+ var $targetOption = $(event.delegateTarget)
91
+ , $targetValue = $(event.target);
92
+
93
+ if ($targetValue.hasClass('selected')) {
94
+ $targetValue.removeClass('selected');
95
+ $targetValue = $();
96
+ } else {
97
+ $targetValue.addClass('selected').siblings().removeClass('selected');
98
+
99
+ self.$options.find('ul').not($targetOption).each(function(index, element) {
100
+ var $currentOption = $(element)
101
+ , $currentValue = $currentOption.children('.selected')
102
+ , $otherOption = self.$options.find('ul').not($targetOption.add($currentOption))
103
+ , $otherValue = $otherOption.children('.selected')
104
+ , options = [];
105
+
106
+ if (!$currentValue.length) return true;
107
+
108
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
109
+ options.push({ name: $targetOption.data('name'), value: $targetValue.data('value') });
110
+
111
+ if (!!!self.getVariantFromOptions(options)) {
112
+ $currentValue.removeClass('selected');
113
+ } else if ($otherOption.length && $otherValue.length) {
114
+ options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
115
+ if (!!!self.getVariantFromOptions(options)) $otherValue.removeClass('selected');
116
+ }
117
+ });
118
+
119
+ $targetOption.children().each(function(index, element) {
120
+ var $currentOption = $targetOption
121
+ , $currentValue = $(element)
122
+ , $otherOption = self.$options.find('ul').not($targetOption).first()
123
+ , $otherValue = $otherOption.children('.selected')
124
+ , $otherOtherOption = self.$options.find('ul').not($targetOption.add($otherOption))
125
+ , $otherOtherValue = $otherOtherOption.children('.selected')
126
+ , options = [];
127
+
128
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
129
+ if ($otherOption.length && $otherValue.length) options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
130
+ if ($otherOtherOption.length && $otherOtherValue.length) options.push({ name: $otherOtherOption.data('name'), value: $otherOtherValue.data('value') });
131
+ self.toggleOptionValue($currentValue, !!self.getVariantFromOptions(options));
132
+ });
133
+ }
134
+
135
+ self.$options.find('ul').not($targetOption).each(function(index, element) {
136
+ var $currentOption = $(element);
137
+
138
+ $currentOption.children().each(function(index, element) {
139
+ var $currentValue = $(element)
140
+ , $otherOption = self.$options.find('ul').not($targetOption.add($currentOption))
141
+ , $otherValue = $otherOption.children('.selected')
142
+ , options = [];
143
+
144
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
145
+ if ($targetOption.length && $targetValue.length) options.push({ name: $targetOption.data('name'), value: $targetValue.data('value') });
146
+ if ($otherOption.length && $otherValue.length) options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
147
+ self.toggleOptionValue($currentValue, !!self.getVariantFromOptions(options));
148
+ });
149
+ });
150
+
151
+ self.setVariant(self.getVariantFromOptions(self.getCurrentOptions()));
152
+ };
153
+
154
+ //
155
+ // Option Methods
156
+ //
157
+
158
+ self.getOptionsFromProduct = function() {
159
+ return _.compact([
160
+ self.product.option1 ? self.product.option1 : undefined,
161
+ self.product.option2 ? self.product.option2 : undefined,
162
+ self.product.option3 ? self.product.option3 : undefined
163
+ ]);
164
+ };
165
+
166
+
167
+ self.getOptionsFromVariant = function(variant) {
168
+ return _.compact([
169
+ self.product.option1 ? { name: self.product.option1, value: variant.option1 } : undefined,
170
+ self.product.option2 ? { name: self.product.option2, value: variant.option2 } : undefined,
171
+ self.product.option3 ? { name: self.product.option3, value: variant.option3 } : undefined
172
+ ]);
173
+ };
174
+
175
+ self.getOptionsWithAllValues = function() {
176
+ return _.map(self.getOptionsFromProduct(), function(optionName) {
177
+ return {
178
+ name: optionName,
179
+ values: _.uniq(_.map(self.product.variants, function(variant) {
180
+ return variant[self.getOptionAttribute(optionName)];
181
+ }))
182
+ };
183
+ });
184
+ };
185
+
186
+ self.getOptionAttribute = function(option) {
187
+ optionName = _.isObject(option) ? option.name : option;
188
+
189
+ if (self.product.option1 == optionName) {
190
+ return 'option1';
191
+ } else if (self.product.option2 == optionName) {
192
+ return 'option2';
193
+ } else if (self.product.option3 == optionName) {
194
+ return 'option3';
195
+ }
196
+ };
197
+
198
+ self.getCurrentOptions = function() {
199
+ var options = [];
200
+
201
+ self.$options.children('ul').each(function(index, element) {
202
+ var $option = $(element);
203
+
204
+ options.push({
205
+ name: $option.data('name'),
206
+ value: $option.children('.selected').first().data('value')
207
+ });
208
+ });
209
+
210
+ return options;
211
+ };
212
+
213
+ self.toggleOptionValue = function($value, on) {
214
+ if (on) {
215
+ $value.addClass('available').removeClass('unavailable');
216
+ } else {
217
+ $value.addClass('unavailable').removeClass('available selected');
218
+ }
219
+ };
220
+
221
+ //
222
+ // Variant Methods
223
+ //
224
+
225
+ self.getInitialVariant = function () {
226
+ var variant = _.find(self.product.variants, function(variant) {
227
+ return variant.quantity > 0;
228
+ });
229
+
230
+ if (!variant) {
231
+ variant = _.first(self.product.variants);
232
+ self.outOfStock();
233
+ }
234
+
235
+ return variant;
236
+ };
237
+
238
+ self.getVariantFromOptions = function(options) {
239
+ if (_.find(options, function(option) { return option.value == undefined })) return false;
240
+
241
+ var attributes = _.object(_.map(options, function(option) {
242
+ return [self.getOptionAttribute(option.name), option.value.toString()]
243
+ }));
244
+
245
+ var variants = _.sortBy(_.where(self.product.variants, attributes), function(variant) { return variant.price });
246
+ return _.find(variants, function(variant) { return variant.quantity > 0 });
247
+ };
248
+
249
+ self.setOptionsFromVariant = function(variant) {
250
+ if (variant.option1) $('#option1 li[data-value="' + variant.option1 + '"]', self.$options).click();
251
+ if (variant.option1) $('#option2 li[data-value="' + variant.option2 + '"]', self.$options).click();
252
+ if (variant.option1) $('#option3 li[data-value="' + variant.option3 + '"]', self.$options).click();
253
+ };
254
+
255
+ self.setVariant = function(variant) {
256
+ self.variant = variant;
257
+ Caboose.Store.Modules.Cart.setVariant(variant);
258
+ if (variant) self.setImageFromVariant(variant);
259
+ if (variant && self.$price.length) self.$price.empty().text('$' + parseFloat((variant.price * 100) / 100).toFixed(2));
260
+ };
261
+
262
+ self.getVariant = function(id) {
263
+ return _.find(self.product.variants, function(variant) { return variant.id == (id || self.variant.id) });
264
+ };
265
+
266
+ //
267
+ // Image Methods
268
+ //
269
+
270
+ self.setImageFromVariant = function(variant) {
271
+ var $figure = self.$images.children('figure');
272
+
273
+ if (variant.images && variant.images.length > 0) {
274
+ $figure.css('background-image', 'url(' + variant.images[0].urls.large + ')');
275
+ } else if ($figure.css('background-image').toLowerCase() == 'none') {
276
+ $figure.css('background-image', 'url(' + _.first(self.product.images).urls.large + ')');
277
+ }
278
+ };
279
+
280
+ return self;
281
+ }).call(Caboose.Store);
282
+
@@ -14,7 +14,7 @@
14
14
  */
15
15
 
16
16
  #cboxLoadedContent { margin-bottom: 0; }
17
-
17
+
18
18
  body {
19
19
  margin: 0;
20
20
  padding: 0;
@@ -77,7 +77,7 @@ body {
77
77
  height: 80px;
78
78
  background: #e1e1e1;
79
79
  border-bottom: #aaa 1px solid;
80
- font-size: 36pt;
80
+ font-size: 27px !important;
81
81
  }
82
82
 
83
83
  #content h1.model_attribute_h1 {
@@ -86,7 +86,7 @@ body {
86
86
  height: auto;
87
87
  background: transparent;
88
88
  border-bottom: none;
89
- font-size: 36pt;
89
+ font-size: 27px !important;
90
90
  }
91
91
 
92
92
  p.current_page_editing {
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * You're free to add application-wide styles to this file and they'll appear at the top of the
9
9
  * compiled file, but it's generally better to create a new file per style scope.
10
- *
10
+ *
11
11
  *= require colorbox-rails
12
12
  *= require caboose/fonts
13
13
  *= require caboose/page_bar_generator
@@ -15,4 +15,4 @@
15
15
  *= require application
16
16
  */
17
17
 
18
- #cboxLoadedContent { margin-bottom: 0; }
18
+ #cboxLoadedContent { margin-bottom: 0; }
@@ -237,3 +237,4 @@ Modeljs
237
237
  clear: both;
238
238
  line-height: 0;
239
239
  }
240
+
@@ -0,0 +1,7 @@
1
+ <form action="/cart/items" method="post">
2
+ <input type="hidden" name="variant_id" />
3
+ <label for="quantity">Qty:</label>
4
+ <input type="text" name="quantity" value="1" />
5
+ <input type="submit" value="Add To Cart" />
6
+ </form>
7
+
@@ -0,0 +1,41 @@
1
+ <h3>Shopping Cart</h3>
2
+
3
+ <% if (!order.line_items.length) { %>
4
+ <p>Your cart is currently empty. <a href="/products">Click here</a> to continue shopping.</p>
5
+ <% } else { %>
6
+ <ul>
7
+ <li>
8
+ <header>Quantity</header>
9
+ <header>Price</header>
10
+ </li>
11
+
12
+ <% _.each(order.line_items, function(lineItem) { %>
13
+ <li data-id="<%= lineItem.id %>">
14
+ <section>
15
+ <% if (lineItem.variant.images.length > 0) { %>
16
+ <figure style="background-image: url(<%= lineItem.variant.images[0].urls.thumb %>)"></figure>
17
+ <% } else { %>
18
+ <figure style="background-image: url(<%= lineItem.product.images[0].urls.thumb %>)"></figure>
19
+ <% } %>
20
+
21
+ <p><%= lineItem.title %><br /><a id="remove-from-cart"t="remove">Remove</a><a href="/products/<%= lineItem.variant.product_id %>">View</a></p>
22
+ </section>
23
+
24
+ <section>
25
+ <input name="quantity" type="text" value="<%= lineItem.quantity %>" />
26
+ </section>
27
+
28
+ <section>
29
+ <p class="price">$<%= lineItem.price %></p>
30
+ </section>
31
+ </li>
32
+ <% }); %>
33
+
34
+ <li>
35
+ <footer>
36
+ <a href="/checkout" class="btn blue">Proceed to Checkout</a>
37
+ <h4>Subtotal: <span class="subtotal">$<%= parseFloat(Math.round(order.subtotal * 100) / 100).toFixed(2) %></span></h4>
38
+ </footer>
39
+ </li>
40
+ </ul>
41
+ <% } %>
@@ -0,0 +1,53 @@
1
+ <div class="wrapper">
2
+ <form action="/checkout/address" method="put">
3
+ <section>
4
+ <fieldset id="shipping">
5
+ <h3>Shipping Address</h3>
6
+ <label><span>First Name</span> <input name="shipping[first_name]" type="text" value="<%= shippingAddress ? shippingAddress.first_name : "" %>" /></label>
7
+ <label><span>Last Name</span> <input name="shipping[last_name]" type="text" value="<%= shippingAddress ? shippingAddress.last_name : "" %>" /></label>
8
+ <label><span>Company</span> <input name="shipping[company]" type="text" value="<%= shippingAddress ? shippingAddress.company : "" %>" /></label>
9
+ <label><span>Address 1</span> <input name="shipping[address1]" type="text" value="<%= shippingAddress ? shippingAddress.address1 : "" %>" /></label>
10
+ <label><span>Address 2</span> <input name="shipping[address2]" type="text" value="<%= shippingAddress ? shippingAddress.address2 : "" %>" /></label>
11
+ <label><span>City</span> <input name="shipping[city]" type="text" value="<%= shippingAddress ? shippingAddress.city : "" %>" /></label>
12
+
13
+ <label>
14
+ <span>State</span>
15
+
16
+ <select name="shipping[state]">
17
+ <% _.each(states, function(state, abbr) { %>
18
+ <option value="<%= abbr %>" <%= shippingAddress && shippingAddress.state == abbr ? 'selected' : "" %>><%= state %></option>
19
+ <% }); %>
20
+ </select>
21
+ </label>
22
+
23
+ <label><span>Zip</span> <input name="shipping[zip]" type="text" value="<%= shippingAddress ? shippingAddress.zip : "" %>" /></label>
24
+ <label><input name="use_as_billing" type="checkbox" value="false" /> Use as billing address</label>
25
+ </fieldset>
26
+ </section>
27
+
28
+ <section>
29
+ <fieldset id="billing">
30
+ <h3>Billing Address</h3>
31
+ <label><span>First Name</span> <input name="billing[first_name]" type="text" value="<%= billingAddress ? billingAddress.first_name : "" %>" /></label>
32
+ <label><span>Last Name</span> <input name="billing[last_name]" type="text" value="<%= billingAddress ? billingAddress.last_name : "" %>" /></label>
33
+ <label><span>Company</span> <input name="billing[company]" type="text" value="<%= billingAddress ? billingAddress.company : "" %>" /></label>
34
+ <label><span>Address 1</span> <input name="billing[address1]" type="text" value="<%= billingAddress ? billingAddress.address1 : "" %>" /></label>
35
+ <label><span>Address 2</span> <input name="billing[address2]" type="text" value="<%= billingAddress ? billingAddress.address2 : "" %>" /></label>
36
+ <label><span>City</span> <input name="billing[city]" type="text" value="<%= billingAddress ? billingAddress.city : "" %>" /></label>
37
+
38
+ <label>
39
+ <span>State</span>
40
+
41
+ <select name="billing[state]">
42
+ <% _.each(states, function(state, abbr) { %>
43
+ <option value="<%= abbr %>" <%= billingAddress && billingAddress.state == abbr ? 'selected' : "" %>><%= state %></option>
44
+ <% }); %>
45
+ </select>
46
+ </label>
47
+
48
+ <label><span>Zip</span> <input name="billing[zip]" type="text" value="<%= billingAddress ? billingAddress.zip : "" %>" /></label>
49
+ </fieldset>
50
+ </section>
51
+ </form>
52
+ </div>
53
+
@@ -0,0 +1,8 @@
1
+ <div class="wrapper">
2
+ <form action="/checkout/attach-guest" method="post">
3
+ <input name="email" type="text" placeholder="Email" />
4
+ <input name="confirm_email" type="email" placeholder="Confirm email" />
5
+ <input type="submit" value="Submit" />
6
+ </form>
7
+ </div>
8
+
@@ -0,0 +1,11 @@
1
+ <div class="wrapper">
2
+ <form action="/register" method="post">
3
+ <input name="first_name" type="text" placeholder="First Name" />
4
+ <input name="last_name" type="text" placeholder="Last Name" />
5
+ <input name="email" type="text" placeholder="Email" />
6
+ <input name="phone" type="text" placeholder="Phone" />
7
+ <input name="pass1" type="password" placeholder="Password" />
8
+ <input name="pass2" type="password" placeholder="Confirm Password" />
9
+ <input type="submit" value="Submit" />
10
+ </form>
11
+ </div>
@@ -0,0 +1,7 @@
1
+ <div class="wrapper">
2
+ <form action="/login" method="post">
3
+ <input name="username" type="text" placeholder="Email" />
4
+ <input name="password" type="password" placeholder="Password" />
5
+ <input type="submit" value="Submit" />
6
+ </form>
7
+ </div>
@@ -0,0 +1,32 @@
1
+ <p class="wrapper">Your Cart:</p>
2
+
3
+ <ul>
4
+ <% _.each(order.line_items, function(lineItem) { %>
5
+ <li data-id="<%= lineItem.id %>">
6
+ <div class="wrapper">
7
+ <aside>
8
+ <figure style="background-image: url(<%= lineItem.variant.images[0].urls.thumb %>)"></figure>
9
+ <p><%= lineItem.title %><br />Qty: <%= lineItem.quantity %><br /><span class="price">$<%= ((parseFloat(lineItem.price) * 100) / 100).toFixed(2) %></span></p>
10
+ </aside>
11
+
12
+ <section>
13
+ <p>$<%= ((parseFloat(lineItem.price) * 100) / 100).toFixed(2) %></p>
14
+ </section>
15
+ </div>
16
+ </li>
17
+ <% }); %>
18
+ </ul>
19
+
20
+
21
+ <p class="wrapper subtotal"><span>Subtotal:</span> <span>$<%= ((parseFloat(order.subtotal) * 100) / 100).toFixed(2) %></span></p>
22
+
23
+ <% if (order.shipping > 0) { %>
24
+ <p class="wrapper shipping"><span>Shipping & Handling:</span> <span>$<%= (((parseFloat(order.shipping) + parseFloat(order.handling)) * 100) / 100).toFixed(2) %></span></p>
25
+ <% } %>
26
+
27
+ <% if (order.tax > 0 && order.billing_address.state == 'AL') { %>
28
+ <p class="wrapper tax"><span>Tax <small>(if in Alabama)</small>:</span> <span>$<%= parseFloat(Math.round(order.tax * 100) / 100).toFixed(2) %></span></p>
29
+ <% } %>
30
+
31
+ <p class="wrapper total"><span>Total:</span> <span>$<%= parseFloat(Math.round(order.total * 100) / 100).toFixed(2) %></span></p>
32
+
@@ -0,0 +1,21 @@
1
+ <div class="wrapper">
2
+ <ul>
3
+ <li>
4
+ <p>Already a member<p>
5
+ <button data-login-action="signin">Sign in</button>
6
+ </li>
7
+
8
+ <li>
9
+ <p>Sign up for all of our member benefits</p>
10
+ <button data-login-action="register">New Customer</button>
11
+ </li>
12
+
13
+ <li>
14
+ <p>No thanks</p>
15
+ <button data-login-action="continue">Continue As Guest</button>
16
+ </li>
17
+ </ul>
18
+ </div>
19
+
20
+ <section></section>
21
+
@@ -0,0 +1,5 @@
1
+ <div class="wrapper">
2
+ <h3>Complete my purchase</h3>
3
+ <%= form %>
4
+ </div>
5
+
@@ -0,0 +1,18 @@
1
+ <% if (rates) { %>
2
+ <section>
3
+ <div class="wrapper">
4
+ <h3>Shipping Method</h3>
5
+ <p>Please select how you would like your products to be delivered</p>
6
+
7
+ <select name="shipping">
8
+ <option value="">Choose a shipping method</option>
9
+
10
+ <% _.each(rates, function(rate) { %>
11
+ <option value="<%= rate.service_code %>" <% if (selectedRate && selectedRate.service_code == rate.service_code) { %>selected<% } %>>
12
+ <%= '$' + parseFloat(rate.total_price).toFixed(2) + ' - ' + rate.service_name %>
13
+ </option>
14
+ <% }); %>
15
+ </select>
16
+ </div>
17
+ </section>
18
+ <% } %>
@@ -0,0 +1,8 @@
1
+ <figure></figure>
2
+
3
+ <ul>
4
+ <% _.each(images, function(image) { %>
5
+ <li data-id="<%= image.id %>"><figure style="background-image: url(<%= image.urls.thumb %>)" data-url-large="<%= image.urls.large %>"></figure></li>
6
+ <% }); %>
7
+ </ul>
8
+
@@ -0,0 +1,19 @@
1
+ <!--<% _.each(options, function(option, index) { %>
2
+ <select id="<%= 'option' + (index + 1) %>" name="<%= option.name %>">
3
+ <option value="">Choose an Option</option>
4
+
5
+ <% _.each(option.values, function(value) { %>
6
+ <option value="<%= value %>"><%= value %></option>
7
+ <% }); %>
8
+ </select>
9
+ <% }); %>-->
10
+
11
+ <% _.each(options, function(option, index) { %>
12
+ <h3><%= option.name %></h3>
13
+ <ul id="<%= 'option' + (index + 1) %>" data-name="<%= option.name %>">
14
+ <% _.each(option.values, function(value) { %>
15
+ <li data-value="<%= value %>"><%= value %></li>
16
+ <% }); %>
17
+ </ul>
18
+ <% }); %>
19
+
@@ -3,16 +3,6 @@ module CabooseStore
3
3
  class ApplicationController < Caboose::ApplicationController
4
4
  protect_from_forgery
5
5
  layout 'layouts/caboose/application'
6
- before_filter :init_cart
7
-
8
- def init_cart
9
- return if session['cart_id'] && Order.exists?(session['cart_id'])
10
- order = Order.new(:status => 'cart', :date_created => DateTime.now)
11
- order.referring_site = request.env['HTTP_REFERER']
12
- order.landing_page = request.fullpath
13
- order.landing_page_ref = params[:ref] if params[:ref]
14
- order.save
15
- session['cart_id'] = order.id;
16
- end
6
+ helper :all
17
7
  end
18
8
  end