caboose-cms 0.4.151 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +8 -8
  2. data/app/assets/javascripts/caboose/admin_products.js +79 -0
  3. data/app/assets/javascripts/caboose/application.js +2 -1
  4. data/app/assets/javascripts/caboose/cart.js +168 -0
  5. data/app/assets/javascripts/caboose/checkout.js +151 -0
  6. data/app/assets/javascripts/caboose/checkout_module.js +312 -0
  7. data/app/assets/javascripts/caboose/checkout_step1.js +179 -0
  8. data/app/assets/javascripts/caboose/checkout_step2.js +39 -0
  9. data/app/assets/javascripts/caboose/checkout_step3.js +34 -0
  10. data/app/assets/javascripts/caboose/checkout_step4.js +97 -0
  11. data/app/assets/javascripts/caboose/main.js +99 -8
  12. data/app/assets/javascripts/caboose/product.js +284 -0
  13. data/app/assets/stylesheets/caboose/admin_products.css +86 -0
  14. data/app/assets/templates/caboose/cart/add_to_cart.jst.ejs +7 -0
  15. data/app/assets/templates/caboose/cart/line_items.jst.ejs +41 -0
  16. data/app/assets/templates/caboose/checkout/address.jst.ejs +53 -0
  17. data/app/assets/templates/caboose/checkout/forms/guest.jst.ejs +8 -0
  18. data/app/assets/templates/caboose/checkout/forms/register.jst.ejs +11 -0
  19. data/app/assets/templates/caboose/checkout/forms/signin.jst.ejs +7 -0
  20. data/app/assets/templates/caboose/checkout/line_items.jst.ejs +31 -0
  21. data/app/assets/templates/caboose/checkout/login.jst.ejs +21 -0
  22. data/app/assets/templates/caboose/checkout/payment.jst.ejs +5 -0
  23. data/app/assets/templates/caboose/checkout/shipping.jst.ejs +18 -0
  24. data/app/assets/templates/caboose/product/images.jst.ejs +8 -0
  25. data/app/assets/templates/caboose/product/options.jst.ejs +19 -0
  26. data/app/controllers/caboose/application_controller.rb +29 -1
  27. data/app/controllers/caboose/cart_controller.rb +52 -0
  28. data/app/controllers/caboose/categories_controller.rb +108 -0
  29. data/app/controllers/caboose/checkout_controller.rb +325 -0
  30. data/app/controllers/caboose/orders_controller.rb +439 -0
  31. data/app/controllers/caboose/product_images_controller.rb +38 -0
  32. data/app/controllers/caboose/products_controller.rb +737 -0
  33. data/app/controllers/caboose/reviews_controller.rb +15 -0
  34. data/app/controllers/caboose/variants_controller.rb +218 -0
  35. data/app/controllers/caboose/vendors_controller.rb +73 -0
  36. data/app/helpers/caboose/application_helper.rb +4 -0
  37. data/app/helpers/caboose/categories_helper.rb +82 -0
  38. data/app/helpers/caboose/checkout_helper.rb +20 -0
  39. data/app/helpers/caboose/products_helper.rb +8 -0
  40. data/app/mailers/caboose/orders_mailer.rb +30 -0
  41. data/app/models/caboose/address.rb +26 -0
  42. data/app/models/caboose/category.rb +89 -0
  43. data/app/models/caboose/category_membership.rb +10 -0
  44. data/app/models/caboose/core_plugin.rb +15 -37
  45. data/app/models/caboose/customization_membership.rb +10 -0
  46. data/app/models/caboose/discount.rb +16 -0
  47. data/app/models/caboose/line_item.rb +81 -0
  48. data/app/models/caboose/message.rb +20 -0
  49. data/app/models/caboose/order.rb +191 -0
  50. data/app/models/caboose/order_discount.rb +10 -0
  51. data/app/models/caboose/order_pdf.rb +78 -0
  52. data/app/models/caboose/payment_processors/authorizenet.rb +53 -0
  53. data/app/models/caboose/payment_processors/base.rb +39 -0
  54. data/app/models/caboose/payment_processors/payscape.rb +94 -0
  55. data/app/models/caboose/product.rb +145 -0
  56. data/app/models/caboose/product_image.rb +62 -0
  57. data/app/models/caboose/product_image_variant.rb +10 -0
  58. data/app/models/caboose/review.rb +13 -0
  59. data/app/models/caboose/schema.rb +205 -1
  60. data/app/models/caboose/search_filter.rb +191 -0
  61. data/app/models/caboose/shipping_calculator.rb +81 -0
  62. data/app/models/caboose/states.rb +61 -52
  63. data/app/models/caboose/tax_calculator.rb +23 -0
  64. data/app/models/caboose/tax_line.rb +9 -0
  65. data/app/models/caboose/variant.rb +99 -0
  66. data/app/models/caboose/vendor.rb +22 -0
  67. data/app/views/caboose/cart/index.html.erb +8 -0
  68. data/app/views/caboose/categories/admin_edit.html.erb +79 -0
  69. data/app/views/caboose/categories/admin_index.html.erb +11 -0
  70. data/app/views/caboose/categories/admin_new.html.erb +62 -0
  71. data/app/views/caboose/checkout/_address_form.html.erb +111 -0
  72. data/app/views/caboose/checkout/_billing_form.html.erb +47 -0
  73. data/app/views/caboose/checkout/_cart.html.erb +52 -0
  74. data/app/views/caboose/checkout/_confirm.html.erb +61 -0
  75. data/app/views/caboose/checkout/_order_discount.html.erb +40 -0
  76. data/app/views/caboose/checkout/_shipping_address.html.erb +10 -0
  77. data/app/views/caboose/checkout/_shipping_method.html.erb +2 -0
  78. data/app/views/caboose/checkout/_shipping_method_form.html.erb +21 -0
  79. data/app/views/caboose/checkout/billing.html.erb +11 -0
  80. data/app/views/caboose/checkout/discount.html.erb +11 -0
  81. data/app/views/caboose/checkout/empty.html.erb +2 -0
  82. data/app/views/caboose/checkout/error.html.erb +2 -0
  83. data/app/views/caboose/checkout/index.html.erb +43 -0
  84. data/app/views/caboose/checkout/login.html.erb +2 -0
  85. data/app/views/caboose/checkout/payment.html.erb +79 -0
  86. data/app/views/caboose/checkout/relay.html.erb +23 -0
  87. data/app/views/caboose/checkout/relay_old.html.erb +12 -0
  88. data/app/views/caboose/checkout/relay_postMessage.html.erb +19 -0
  89. data/app/views/caboose/checkout/shipping.html.erb +15 -0
  90. data/app/views/caboose/checkout/step_four.html.erb +93 -0
  91. data/app/views/caboose/checkout/step_one.html.erb +56 -0
  92. data/app/views/caboose/checkout/step_one_old.html.erb +13 -0
  93. data/app/views/caboose/checkout/step_three.html.erb +23 -0
  94. data/app/views/caboose/checkout/step_two.html.erb +52 -0
  95. data/app/views/caboose/checkout/step_two_old.html.erb +14 -0
  96. data/app/views/caboose/checkout/thanks.html.erb +5 -0
  97. data/app/views/caboose/orders/_admin_footer.html.erb +2 -0
  98. data/app/views/caboose/orders/_admin_header.html.erb +31 -0
  99. data/app/views/caboose/orders/_quickbooks_order.html.erb +0 -0
  100. data/app/views/caboose/orders/admin_delete_form.html.erb +21 -0
  101. data/app/views/caboose/orders/admin_edit.html.erb +271 -0
  102. data/app/views/caboose/orders/admin_index.html.erb +89 -0
  103. data/app/views/caboose/orders/admin_new.html.erb +42 -0
  104. data/app/views/caboose/orders/admin_print.html.erb +72 -0
  105. data/app/views/caboose/orders_mailer/customer_new_order.html.erb +1 -0
  106. data/app/views/caboose/orders_mailer/customer_status_updated.html.erb +1 -0
  107. data/app/views/caboose/orders_mailer/fulfillment_new_order.html.erb +1 -0
  108. data/app/views/caboose/orders_mailer/shipping_order_ready.html.erb +1 -0
  109. data/app/views/caboose/products/_admin_footer.html.erb +2 -0
  110. data/app/views/caboose/products/_admin_header.html.erb +32 -0
  111. data/app/views/caboose/products/_sort_options.html.erb +19 -0
  112. data/app/views/caboose/products/admin_add_upcs.html.erb +58 -0
  113. data/app/views/caboose/products/admin_delete_form.html.erb +21 -0
  114. data/app/views/caboose/products/admin_edit_categories.html.erb +73 -0
  115. data/app/views/caboose/products/admin_edit_category_images.html.erb +233 -0
  116. data/app/views/caboose/products/admin_edit_description.html.erb +38 -0
  117. data/app/views/caboose/products/admin_edit_general.html.erb +104 -0
  118. data/app/views/caboose/products/admin_edit_images.html.erb +236 -0
  119. data/app/views/caboose/products/admin_edit_options.html.erb +51 -0
  120. data/app/views/caboose/products/admin_edit_seo.html.erb +37 -0
  121. data/app/views/caboose/products/admin_edit_variant_columns.html.erb +75 -0
  122. data/app/views/caboose/products/admin_edit_variant_sort_order.html.erb +63 -0
  123. data/app/views/caboose/products/admin_edit_variants.html.erb +171 -0
  124. data/app/views/caboose/products/admin_edit_variants_single.html.erb +68 -0
  125. data/app/views/caboose/products/admin_group_variants.html.erb +433 -0
  126. data/app/views/caboose/products/admin_index.html.erb +95 -0
  127. data/app/views/caboose/products/admin_new.html.erb +41 -0
  128. data/app/views/caboose/products/admin_sort.html copy.erb +155 -0
  129. data/app/views/caboose/products/admin_sort.html.erb +254 -0
  130. data/app/views/caboose/products/details.html.erb +438 -0
  131. data/app/views/caboose/products/index.html.erb +46 -0
  132. data/app/views/caboose/products/not_available.html.erb +35 -0
  133. data/app/views/caboose/variants/admin_edit.html.erb +82 -0
  134. data/app/views/caboose/variants/admin_group.html.erb +184 -0
  135. data/app/views/caboose/variants/admin_new.html.erb +59 -0
  136. data/app/views/caboose/vendors/admin_edit.html.erb +24 -0
  137. data/app/views/caboose/vendors/admin_index.html.erb +30 -0
  138. data/app/views/caboose/vendors/admin_new.html.erb +34 -0
  139. data/app/views/layouts/caboose/store/_banner.html.erb +10 -0
  140. data/app/views/layouts/caboose/store/_banner2.html.erb +10 -0
  141. data/app/views/layouts/caboose/store/_footer.html.erb +55 -0
  142. data/app/views/layouts/caboose/store/_header.html.erb +69 -0
  143. data/app/views/layouts/caboose/store/_sidebar.html.erb +27 -0
  144. data/app/views/layouts/caboose/store/application.html.erb +33 -0
  145. data/app/views/layouts/caboose/store/authorize_net.erb +18 -0
  146. data/app/views/layouts/caboose/store/layout_about.html.erb +42 -0
  147. data/app/views/layouts/caboose/store/layout_blog.html.erb +159 -0
  148. data/app/views/layouts/caboose/store/layout_confirm.html.erb +85 -0
  149. data/app/views/layouts/caboose/store/layout_contact.html.erb +38 -0
  150. data/app/views/layouts/caboose/store/layout_default.html.erb +10 -0
  151. data/app/views/layouts/caboose/store/layout_detail.html.erb +114 -0
  152. data/app/views/layouts/caboose/store/layout_order.html.erb +77 -0
  153. data/app/views/layouts/caboose/store/layout_pricing.html.erb +182 -0
  154. data/app/views/layouts/caboose/store/layout_product.html.erb +110 -0
  155. data/app/views/layouts/caboose/store/layout_profile.html.erb +55 -0
  156. data/app/views/layouts/caboose/store/layout_single.html.erb +3 -0
  157. data/app/views/layouts/caboose/store/layout_testimonial.html.erb +110 -0
  158. data/app/views/layouts/caboose/store/layout_testing.html.erb +4 -0
  159. data/config/routes.rb +126 -0
  160. data/lib/caboose.rb +46 -1
  161. data/lib/caboose/engine.rb +39 -1
  162. data/lib/caboose/version.rb +1 -1
  163. data/lib/tasks/caboose.rake +12 -0
  164. metadata +151 -4
  165. data/app/assets/javascripts/caboose/admin_page_edit_content_bak.js +0 -164
  166. data/app/assets/javascripts/caboose/model/#Untitled-1# +0 -2
@@ -0,0 +1,284 @@
1
+ //
2
+ // Product
3
+ //
4
+
5
+ Caboose.Store.Modules.Product = (function() {
6
+ var self = {
7
+ templates: {
8
+ images: JST['caboose/product/images'],
9
+ options: JST['caboose/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.option1_values = response.option1_values;
25
+ self.option2_values = response.option2_values;
26
+ self.option3_values = response.option3_values;
27
+ self.render();
28
+ self.bindEvents();
29
+ self.setVariant(self.getInitialVariant());
30
+ self.setOptionsFromVariant(self.variant);
31
+ });
32
+ };
33
+
34
+ //
35
+ // Render
36
+ //
37
+
38
+ self.render = function() {
39
+ var renderFunctions = [];
40
+ renderFunctions.push(self.renderImages);
41
+ renderFunctions.push(self.renderOptions);
42
+
43
+ _.each(renderFunctions, function(renderFunction, index) {
44
+ var finished = index == (renderFunctions.length - 1);
45
+
46
+ renderFunction(function() {
47
+ if (finished) self.$product.removeClass('loading');
48
+ });
49
+ });
50
+ };
51
+
52
+ self.renderImages = function(callback) {
53
+ self.$images = $('#product-images', self.$product);
54
+ if (!self.$images.length) return false;
55
+ self.$images.empty().html(self.templates.images({ images: self.product.images }));
56
+ if (callback) callback();
57
+ };
58
+
59
+ self.renderOptions = function(callback) {
60
+ self.$options = $('#product-options', self.$options);
61
+ if (!self.$options.length) return false;
62
+ self.$options.empty().html(self.templates.options({ options: self.getOptionsWithAllValues() }));
63
+ if (callback) callback();
64
+ };
65
+
66
+ //
67
+ // Out of Stock
68
+ //
69
+
70
+ self.outOfStock = function() {
71
+ self.$product.find('#add-to-cart').after($('<p/>').addClass('message error').text('Out of Stock')).remove();
72
+ };
73
+
74
+ //
75
+ // Events
76
+ //
77
+
78
+ self.bindEvents = function() {
79
+ self.$images.find('ul > li > figure').on('click', self.thumbClickHandler);
80
+ self.$images.children('figure').on('click', self.imageClickHandler);
81
+ self.$options.find('ul').on('click', 'li', self.optionClickHandler);
82
+ };
83
+
84
+ self.thumbClickHandler = function(event) {
85
+ self.$images.children('figure').css('background-image', 'url(' + $(event.target).data('url-large') + ')');
86
+ };
87
+
88
+ self.imageClickHandler = function(event) {
89
+ window.location = $(event.target).css('background-image').match(/^url\("(.*)"\)$/)[1];
90
+ };
91
+
92
+ self.optionClickHandler = function(event) {
93
+ var $targetOption = $(event.delegateTarget)
94
+ , $targetValue = $(event.target);
95
+
96
+ if ($targetValue.hasClass('selected')) {
97
+ $targetValue.removeClass('selected');
98
+ $targetValue = $();
99
+ } else {
100
+ $targetValue.addClass('selected').siblings().removeClass('selected');
101
+
102
+ self.$options.find('ul').not($targetOption).each(function(index, element) {
103
+ var $currentOption = $(element)
104
+ , $currentValue = $currentOption.children('.selected')
105
+ , $otherOption = self.$options.find('ul').not($targetOption.add($currentOption))
106
+ , $otherValue = $otherOption.children('.selected')
107
+ , options = [];
108
+
109
+ if (!$currentValue.length) return true;
110
+
111
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
112
+ options.push({ name: $targetOption.data('name'), value: $targetValue.data('value') });
113
+
114
+ if (!!!self.getVariantFromOptions(options)) {
115
+ $currentValue.removeClass('selected');
116
+ } else if ($otherOption.length && $otherValue.length) {
117
+ options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
118
+ if (!!!self.getVariantFromOptions(options)) $otherValue.removeClass('selected');
119
+ }
120
+ });
121
+
122
+ $targetOption.children().each(function(index, element) {
123
+ var $currentOption = $targetOption
124
+ , $currentValue = $(element)
125
+ , $otherOption = self.$options.find('ul').not($targetOption).first()
126
+ , $otherValue = $otherOption.children('.selected')
127
+ , $otherOtherOption = self.$options.find('ul').not($targetOption.add($otherOption))
128
+ , $otherOtherValue = $otherOtherOption.children('.selected')
129
+ , options = [];
130
+
131
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
132
+ if ($otherOption.length && $otherValue.length) options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
133
+ if ($otherOtherOption.length && $otherOtherValue.length) options.push({ name: $otherOtherOption.data('name'), value: $otherOtherValue.data('value') });
134
+ self.toggleOptionValue($currentValue, !!self.getVariantFromOptions(options));
135
+ });
136
+ }
137
+
138
+ self.$options.find('ul').not($targetOption).each(function(index, element) {
139
+ var $currentOption = $(element);
140
+
141
+ $currentOption.children().each(function(index, element) {
142
+ var $currentValue = $(element)
143
+ , $otherOption = self.$options.find('ul').not($targetOption.add($currentOption))
144
+ , $otherValue = $otherOption.children('.selected')
145
+ , options = [];
146
+
147
+ options.push({ name: $currentOption.data('name'), value: $currentValue.data('value') });
148
+ if ($targetOption.length && $targetValue.length) options.push({ name: $targetOption.data('name'), value: $targetValue.data('value') });
149
+ if ($otherOption.length && $otherValue.length) options.push({ name: $otherOption.data('name'), value: $otherValue.data('value') });
150
+ self.toggleOptionValue($currentValue, !!self.getVariantFromOptions(options));
151
+ });
152
+ });
153
+
154
+ self.setVariant(self.getVariantFromOptions(self.getCurrentOptions()));
155
+ };
156
+
157
+ //
158
+ // Option Methods
159
+ //
160
+
161
+ self.getOptionsFromProduct = function() {
162
+ return _.compact([
163
+ self.product.option1 ? self.product.option1 : undefined,
164
+ self.product.option2 ? self.product.option2 : undefined,
165
+ self.product.option3 ? self.product.option3 : undefined
166
+ ]);
167
+ };
168
+
169
+
170
+ self.getOptionsFromVariant = function(variant) {
171
+ return _.compact([
172
+ self.product.option1 ? { name: self.product.option1, value: variant.option1 } : undefined,
173
+ self.product.option2 ? { name: self.product.option2, value: variant.option2 } : undefined,
174
+ self.product.option3 ? { name: self.product.option3, value: variant.option3 } : undefined
175
+ ]);
176
+ };
177
+
178
+ self.getOptionsWithAllValues = function() {
179
+ var options = [];
180
+ if (self.product.option1) options.push({ name: self.product.option1, values: self.option1_values });
181
+ if (self.product.option2) options.push({ name: self.product.option2, values: self.option2_values });
182
+ if (self.product.option3) options.push({ name: self.product.option3, values: self.option3_values });
183
+ return options;
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_in_stock > 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_in_stock > 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
+ if (!variant || !variant.images || variant.images.length == 0 || !variant.images[0]) return;
272
+ self.$product.trigger('variant:updated');
273
+
274
+ var $figure = self.$images.children('figure');
275
+ if (variant.images && variant.images.length > 0 && variant.images[0]) {
276
+ $figure.css('background-image', 'url(' + variant.images[0].urls.large + ')');
277
+ } else if ($figure.css('background-image').toLowerCase() == 'none') {
278
+ $figure.css('background-image', 'url(' + _.first(self.product.images).urls.large + ')');
279
+ }
280
+ };
281
+
282
+ return self;
283
+ }).call(Caboose.Store);
284
+
@@ -0,0 +1,86 @@
1
+
2
+ #modal_tabs {
3
+ width: 200px;
4
+ float: left;
5
+ /*
6
+ position: absolute;
7
+ top: 41px;
8
+ left: 0;
9
+ */
10
+ list-style: none;
11
+ margin: 0;
12
+ padding: 0;
13
+ border-top: #ccc 1px solid;
14
+ }
15
+ #modal_tabs ul li {
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 0;
19
+ }
20
+ #modal_tabs li.back {
21
+ padding: 10px 0;
22
+ }
23
+ #modal_tabs a {
24
+ display: block;
25
+ margin: 0;
26
+ padding: 16px 12px 12px 12px;
27
+ text-decoration: none;
28
+ background: #efefef;
29
+ border-bottom: #ccc 1px solid;
30
+ color: #000;
31
+ }
32
+ #modal_tabs a:hover {
33
+ background: #666;
34
+ color: #fff;
35
+ }
36
+ #modal_tabs li.selected a {
37
+ background: transparent;
38
+ color: #000;
39
+ font-weight: bold;
40
+ }
41
+ #modal_content2 {
42
+ margin-left: 220px;
43
+ }
44
+ #modal_content h1 {
45
+ height: 30px;
46
+ padding-bottom: 10px;
47
+ border-bottom: #666 1px dotted;
48
+ }
49
+ #variants_wrapper {
50
+ width: 100%;
51
+ }
52
+ #variants {
53
+ border-collapse: collapse;
54
+ }
55
+ #variants td {
56
+ margin: 0;
57
+ padding: 0;
58
+ border: #666 1px dotted;
59
+ }
60
+ #variants td input[type='text'] {
61
+ background: transparent;
62
+ color: #000;
63
+ border: 0;
64
+ font-size: 75%;
65
+ }
66
+ #variants th {
67
+ font-size: 85%;
68
+ }
69
+ #variants td.edit a {
70
+ display: block;
71
+ padding: 12px 12px;
72
+ border: 0;
73
+ }
74
+ #variants td.edit a:hover {
75
+ background: #333;
76
+ color: #fff;
77
+ }
78
+ #variants td.delete a {
79
+ display: block;
80
+ padding: 12px 12px;
81
+ border: 0;
82
+ }
83
+ #variants td.delete a:hover {
84
+ background: #333;
85
+ color: #fff;
86
+ }
@@ -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">$<%= parseFloat(Math.round(lineItem.price * 100) / 100).toFixed(2) %></p>
30
+ </section>
31
+ </li>
32
+ <% }); %>
33
+
34
+ <li>
35
+ <footer>
36
+ <a href="/checkout" class="btn blue">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
+