caboose-cms 0.8.43 → 0.8.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/caboose/admin_page_edit_content.js +83 -70
  3. data/app/assets/javascripts/caboose/card.js +2432 -0
  4. data/app/assets/javascripts/caboose/clipboard.js +7 -0
  5. data/app/assets/javascripts/caboose/modal_controllers/modal_block_controller.js +174 -252
  6. data/app/assets/javascripts/caboose/modal_controllers/modal_controller.js +160 -12
  7. data/app/assets/javascripts/caboose/modal_controllers/modal_media_controller.js +419 -0
  8. data/app/assets/javascripts/caboose/modal_integration.js +21 -1
  9. data/app/assets/javascripts/caboose/model/bound_checkbox.js +13 -6
  10. data/app/assets/javascripts/caboose/model/bound_select.js +16 -7
  11. data/app/assets/javascripts/caboose/model/bound_text.js +15 -2
  12. data/app/assets/stylesheets/caboose/admin_block_edit_image.css.scss +16 -1
  13. data/app/assets/stylesheets/caboose/admin_new_block.css +9 -0
  14. data/app/assets/stylesheets/caboose/application.css +2 -1
  15. data/app/assets/stylesheets/caboose/modal_inline.css +8 -15
  16. data/app/assets/stylesheets/caboose/my_account.scss +178 -0
  17. data/app/controllers/caboose/block_types_controller.rb +20 -0
  18. data/app/controllers/caboose/blocks_controller.rb +70 -8
  19. data/app/controllers/caboose/media_controller.rb +39 -3
  20. data/app/models/caboose/block.rb +17 -1
  21. data/app/models/caboose/media.rb +9 -8
  22. data/app/models/caboose/schema.rb +1 -0
  23. data/app/views/caboose/block_types/admin_edit.html.erb +5 -2
  24. data/app/views/caboose/block_types/admin_index.html.erb +2 -1
  25. data/app/views/caboose/my_account/index.html.erb +124 -63
  26. data/app/views/caboose/my_account/index_old.html.erb +191 -0
  27. data/app/views/caboose/pages/admin_edit_content.html.erb +16 -1
  28. data/lib/caboose/version.rb +1 -1
  29. metadata +8 -3
  30. data/app/assets/stylesheets/caboose/my_account.css +0 -2
@@ -77,20 +77,83 @@ module Caboose
77
77
  blocks = []
78
78
  if params[:id]
79
79
  b = Block.find(params[:id])
80
- blocks << { 'id' => b.id, 'children' => admin_tree_helper(b), 'field_type' => b.block_type.field_type }
80
+ bt = b.block_type
81
+ blocks << {
82
+ 'id' => b.id,
83
+ 'parent_id' => b.parent_id,
84
+ 'page_id' => b.page_id,
85
+ 'post_id' => b.post_id,
86
+ 'block_type' => bt,
87
+ 'block_type_id' => bt.id,
88
+ 'children' => admin_tree_helper(b),
89
+ 'field_type' => bt.field_type,
90
+ 'allow_child_blocks' => bt.allow_child_blocks,
91
+ 'use_js_for_modal' => bt.use_js_for_modal,
92
+ 'name' => b.name ? b.name : bt.name,
93
+ 'value' => b.value,
94
+ 'constrain' => b.constrain,
95
+ 'full_width' => b.full_width,
96
+ 'crumbtrail' => self.crumbtrail(b)
97
+ }
81
98
  else
82
99
  q = params[:page_id] ? ["parent_id is null and page_id = ?", params[:page_id]] : ["parent_id is null and post_id = ?", params[:post_id]]
83
- Block.where(q).reorder(:sort_order).all.each do |b|
84
- blocks << { 'id' => b.id, 'allow_child_blocks' => b.block_type.allow_child_blocks, 'children' => admin_tree_helper(b), 'field_type' => b.block_type.field_type }
100
+ Block.where(q).reorder(:sort_order).all.each do |b|
101
+ bt = b.block_type
102
+ blocks << {
103
+ 'id' => b.id,
104
+ 'parent_id' => b.parent_id,
105
+ 'page_id' => b.page_id,
106
+ 'post_id' => b.post_id,
107
+ 'block_type' => bt,
108
+ 'block_type_id' => bt.id,
109
+ 'children' => admin_tree_helper(b),
110
+ 'field_type' => bt.field_type,
111
+ 'allow_child_blocks' => bt.allow_child_blocks,
112
+ 'use_js_for_modal' => bt.use_js_for_modal,
113
+ 'name' => b.name ? b.name : bt.name,
114
+ 'value' => b.value,
115
+ 'constrain' => b.constrain,
116
+ 'full_width' => b.full_width
117
+ }
85
118
  end
86
119
  end
87
120
  render :json => blocks
88
- end
121
+ end
122
+
123
+ def crumbtrail(block)
124
+ crumbs = []
125
+ b = block
126
+ while b
127
+ bt = b.block_type
128
+ crumbs << {
129
+ :block_id => b.id,
130
+ :text => b.name && b.name.downcase != bt.description.downcase ? "#{bt.description} (#{b.name})" : bt.description
131
+ }
132
+ b = b.parent
133
+ end
134
+ return crumbs.reverse
135
+ end
89
136
 
90
137
  def admin_tree_helper(b)
91
138
  arr = []
92
139
  b.children.each do |b2|
93
- arr << { 'id' => b2.id, 'allow_child_blocks' => b2.block_type.allow_child_blocks, 'children' => admin_tree_helper(b2), 'field_type' => b2.block_type.field_type }
140
+ bt = b2.block_type
141
+ arr << {
142
+ 'id' => b2.id,
143
+ 'parent_id' => b2.parent_id,
144
+ 'page_id' => b2.page_id,
145
+ 'post_id' => b2.post_id,
146
+ 'block_type' => bt,
147
+ 'block_type_id' => bt.id,
148
+ 'children' => admin_tree_helper(b2),
149
+ 'field_type' => bt.field_type,
150
+ 'allow_child_blocks' => bt.allow_child_blocks,
151
+ 'use_js_for_modal' => bt.use_js_for_modal,
152
+ 'name' => b2.name ? b2.name : bt.name,
153
+ 'value' => b2.value,
154
+ 'constrain' => b2.constrain,
155
+ 'full_width' => b2.full_width
156
+ }
94
157
  end
95
158
  return arr
96
159
  end
@@ -122,7 +185,7 @@ module Caboose
122
185
  :post => params[:post_id] ? @p : nil,
123
186
  :request => request
124
187
  })
125
- render :json => html
188
+ render :inline => html
126
189
  end
127
190
 
128
191
  # @route GET /admin/pages/:page_id/blocks/render
@@ -212,8 +275,7 @@ module Caboose
212
275
  begin
213
276
  render "caboose/blocks/admin_edit_#{@block.block_type.field_type}", :layout => 'caboose/modal'
214
277
  rescue ActionView::MissingTemplate => ex
215
- render :layout => 'caboose/modal'
216
- Caboose.log('test4')
278
+ render :layout => 'caboose/modal'
217
279
  end
218
280
  end
219
281
  end
@@ -40,13 +40,49 @@ module Caboose
40
40
  render :layout => 'caboose/admin'
41
41
  end
42
42
 
43
+ # @route GET /admin/media/policy
44
+ def admin_policy
45
+ return if !user_is_allowed('media', 'view')
46
+
47
+ config = YAML.load(File.read(Rails.root.join('config', 'aws.yml')))[Rails.env]
48
+ access_key = config['access_key_id']
49
+ secret_key = config['secret_access_key']
50
+ bucket = config['bucket']
51
+ policy = {
52
+ "expiration" => 1.hour.from_now.utc.xmlschema,
53
+ "conditions" => [
54
+ { "bucket" => "#{bucket}-uploads" },
55
+ { "acl" => "public-read" },
56
+ [ "starts-with", "$key", '' ],
57
+ #[ "starts-with", "$Content-Type", 'image/' ],
58
+ [ 'starts-with', '$name', '' ],
59
+ [ 'starts-with', '$Filename', '' ],
60
+ ]
61
+ }
62
+ policy = Base64.encode64(policy.to_json).gsub(/\n/,'')
63
+ render :json => {
64
+ :policy => policy,
65
+ :signature => Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), secret_key, policy)).gsub("\n",""),
66
+ :s3_upload_url => "https://#{bucket}-uploads.s3.amazonaws.com/",
67
+ :aws_access_key_id => access_key,
68
+ :top_media_category => Caboose::MediaCategory.top_category(@site.id),
69
+ }
70
+ end
71
+
43
72
  # @route GET /admin/media/json
44
73
  def admin_json
45
74
  return if !user_is_allowed('media', 'view')
46
75
  render :json => false and return if @site.nil?
47
- id = params[:media_category_id]
48
- cat = id ? MediaCategory.find(id) : MediaCategory.top_category(@site.id)
49
- render :json => cat.api_hash
76
+ #id = params[:media_category_id]
77
+ #cat = id ? MediaCategory.find(id) : MediaCategory.top_category(@site.id)
78
+ #render :json => cat.api_hash
79
+
80
+ arr = Media.where(:media_category_id => params[:media_category_id]).reorder(:sort_order).all
81
+ render :json => arr.collect{ |m| m.api_hash }
82
+
83
+ #cat = id ? MediaCategory.find(id) : MediaCategory.top_category(@site.id)
84
+ #render :json => cat.api_hash
85
+
50
86
  end
51
87
 
52
88
  # @route GET /admin/media/last-upload-processed
@@ -604,6 +604,22 @@ class Caboose::Block < ActiveRecord::Base
604
604
  end
605
605
  end
606
606
  end
607
-
607
+
608
+ def modal_js_block_names
609
+ arr = []
610
+ arr << self.block_type.name if self.block_type.use_js_for_modal
611
+ self.children.each do |b2|
612
+ self.modal_js_controllers_helper(b2, arr)
613
+ end
614
+ return arr
615
+ end
616
+
617
+ def modal_js_controllers_helper(b, arr)
618
+ bt = b.block_type
619
+ arr << bt.name if bt.use_js_for_modal
620
+ b.children.each do |b2|
621
+ self.modal_js_controllers_helper(b2, arr)
622
+ end
623
+ end
608
624
 
609
625
  end
@@ -130,14 +130,15 @@ class Caboose::Media < ActiveRecord::Base
130
130
 
131
131
  def api_hash
132
132
  {
133
- :id => self.id,
134
- :name => self.name,
135
- :original_name => self.original_name,
136
- :description => self.description,
137
- :processed => self.processed,
138
- :image_urls => self.image_urls,
139
- :file_url => self.file ? self.file.url : nil,
140
- :media_type => self.is_image? ? 'image' : 'file'
133
+ :id => self.id,
134
+ :name => self.name,
135
+ :original_name => self.original_name,
136
+ :description => self.description,
137
+ :processed => self.processed,
138
+ :image_urls => self.image_urls,
139
+ :file_url => self.file ? self.file.url : nil,
140
+ :media_type => self.is_image? ? 'image' : 'file',
141
+ :media_category_id => self.media_category_id
141
142
  }
142
143
  end
143
144
 
@@ -180,6 +180,7 @@ class Caboose::Schema < Caboose::Utilities::Schema
180
180
  [ :render_function , :text ],
181
181
  [ :use_render_function , :boolean , { :default => false }],
182
182
  [ :use_render_function_for_layout , :boolean , { :default => false }],
183
+ [ :use_js_for_modal , :boolean , { :default => false }],
183
184
  [ :allow_child_blocks , :boolean , { :default => false }],
184
185
  [ :default_child_block_type_id , :integer ],
185
186
  [ :field_type , :string ],
@@ -28,6 +28,7 @@ bt = @block_type
28
28
  <p><div id='blocktype_<%= bt.id %>_is_global' ></div></p>
29
29
  <p><div id='blocktype_<%= bt.id %>_use_render_function' ></div></p>
30
30
  <p><div id='blocktype_<%= bt.id %>_use_render_function_for_layout' ></div></p>
31
+ <p><div id='blocktype_<%= bt.id %>_use_js_for_modal' ></div></p>
31
32
  <p><div id='blocktype_<%= bt.id %>_allow_child_blocks' ></div></p>
32
33
  <p><div id='blocktype_<%= bt.id %>_default_child_block_type_id' ></div></p>
33
34
  <p><div id='blocktype_<%= bt.id %>_default_constrain' ></div></p>
@@ -95,7 +96,8 @@ $(document).ready(function() {
95
96
  { name: 'block_type_category_id' , sort: 'block_type_category_id' , show: false , bulk_edit: false, nice_name: 'Category' , type: 'select' , value: function(bt) { return bt.block_type_category_id; }, width: 400, options_url: '/admin/block-type-categories/tree-options' },
96
97
  { name: 'is_global' , sort: 'is_global' , show: false , bulk_edit: false, nice_name: 'Global' , type: 'checkbox' , value: function(bt) { return bt.is_global; }, text: function(bt) { return bt.is_global ? 'Yes' : 'No' }, width: 400 },
97
98
  { name: 'use_render_function' , sort: 'use_render_function' , show: true , bulk_edit: false, nice_name: 'Use Render Function' , type: 'checkbox' , value: function(bt) { return bt.use_render_function; }, text: function(bt) { return bt.use_render_function ? 'Yes' : 'No' }, width: 400 },
98
- { name: 'use_render_function_for_layout' , sort: 'use_render_function_for_layout' , show: true , bulk_edit: false, nice_name: 'Use Render Function for Layout' , type: 'checkbox' , value: function(bt) { return bt.use_render_function_for_layout; }, text: function(bt) { return bt.use_render_function_for_layout ? 'Yes' : 'No' }, width: 400 },
99
+ { name: 'use_render_function_for_layout' , sort: 'use_render_function_for_layout' , show: true , bulk_edit: false, nice_name: 'Use Render Function for Modal' , type: 'checkbox' , value: function(bt) { return bt.use_render_function_for_layout; }, text: function(bt) { return bt.use_render_function_for_layout ? 'Yes' : 'No' }, width: 400 },
100
+ { name: 'use_js_for_modal' , sort: 'use_js_for_modal' , show: true , bulk_edit: false, nice_name: 'Use JS for Modal' , type: 'checkbox' , value: function(bt) { return bt.use_js_for_modal; }, text: function(bt) { return bt.use_js_for_modal ? 'Yes' : 'No' }, width: 400 },
99
101
  { name: 'allow_child_blocks' , sort: 'allow_child_blocks' , show: true , bulk_edit: false, nice_name: 'Allow Child Blocks' , type: 'checkbox' , value: function(bt) { return bt.allow_child_blocks; }, text: function(bt) { return bt.allow_child_blocks ? 'Yes' : 'No' }, width: 400 },
100
102
  { name: 'default_child_block_type_id' , sort: 'default_child_block_type_id' , show: false , bulk_edit: false, nice_name: 'Default Child Block Type' , type: 'select' , value: function(bt) { return bt.default_child_block_type_id; }, width: 400, options_url: '/admin/block-types/options' },
101
103
  { name: 'render_function' , sort: 'render_function' , show: false , bulk_edit: false, nice_name: 'Render Function' , type: 'textarea' , value: function(bt) { return bt.render_function; }, width: 800, height: 200 },
@@ -127,7 +129,8 @@ $(document).ready(function() {
127
129
  { name: 'block_type_category_id' , nice_name: 'Category' , type: 'select' , value: <%= raw Caboose.json(bt.block_type_category_id) %>, width: 400, options_url: '/admin/block-type-categories/tree-options' },
128
130
  { name: 'is_global' , nice_name: 'Global' , type: 'checkbox' , value: <%= bt.is_global ? 'true' : 'false' %>, width: 400 },
129
131
  { name: 'use_render_function' , nice_name: 'Use Render Function' , type: 'checkbox' , value: <%= bt.use_render_function ? 'true' : 'false' %>, width: 400 },
130
- { name: 'use_render_function_for_layout' , nice_name: 'Use Render Function for Layout' , type: 'checkbox' , value: <%= bt.use_render_function_for_layout ? 'true' : 'false' %>, width: 400 },
132
+ { name: 'use_render_function_for_layout' , nice_name: 'Use Render Function for Modal' , type: 'checkbox' , value: <%= bt.use_render_function_for_layout ? 'true' : 'false' %>, width: 400 },
133
+ { name: 'use_js_for_modal' , nice_name: 'Use JS for Modal' , type: 'checkbox' , value: <%= bt.use_js_for_modal ? 'true' : 'false' %>, width: 400 },
131
134
  { name: 'allow_child_blocks' , nice_name: 'Allow Child Blocks' , type: 'checkbox' , value: <%= bt.allow_child_blocks ? 'true' : 'false' %>, width: 400 },
132
135
  { name: 'default_child_block_type_id' , nice_name: 'Default Child Block Type' , type: 'select' , value: <%= raw Caboose.json(bt.default_child_block_type_id) %>, text: <%= raw Caboose.json(bt.default_child_block_type) %>, width: 400, options_url: '/admin/block-types/options' },
133
136
  { name: 'render_function' , nice_name: 'Render Function' , type: 'textarea' , value: <%= raw Caboose.json(bt.render_function) %>, width: 800, height: 200 },
@@ -27,7 +27,8 @@ $(document).ready(function() {
27
27
  { name: 'block_type_category_id' , sort: 'block_type_category_id' , show: false , bulk_edit: false, nice_name: 'Category' , type: 'select' , value: function(bt) { return bt.block_type_category_id; }, width: 400, options_url: '/admin/block-type-categories/tree-options' },
28
28
  { name: 'is_global' , sort: 'is_global' , show: false , bulk_edit: false, nice_name: 'Global' , type: 'checkbox' , value: function(bt) { return bt.is_global ? 'Yes' : 'No'; }, width: 20 },
29
29
  { name: 'use_render_function' , sort: 'use_render_function' , show: true , bulk_edit: false, nice_name: 'Use Render Function' , type: 'checkbox' , value: function(bt) { return bt.use_render_function ? 'Yes' : 'No' }, width: 20 },
30
- { name: 'use_render_function_for_layout' , sort: 'use_render_function_for_layout' , show: true , bulk_edit: false, nice_name: 'Use Render Function for Layout' , type: 'checkbox' , value: function(bt) { return bt.use_render_function_for_layout ? 'Yes' : 'No' }, width: 20 },
30
+ { name: 'use_render_function_for_layout' , sort: 'use_render_function_for_layout' , show: true , bulk_edit: false, nice_name: 'Use Render Function for Modal' , type: 'checkbox' , value: function(bt) { return bt.use_render_function_for_layout ? 'Yes' : 'No' }, width: 20 },
31
+ { name: 'use_js_for_modal' , sort: 'use_js_for_modal' , show: true , bulk_edit: false, nice_name: 'Use JS for Modal' , type: 'checkbox' , value: function(bt) { return bt.use_js_for_modal ? 'Yes' : 'No' }, width: 20 },
31
32
  { name: 'allow_child_blocks' , sort: 'allow_child_blocks' , show: true , bulk_edit: false, nice_name: 'Allow Child Blocks' , type: 'checkbox' , value: function(bt) { return bt.allow_child_blocks ? 'Yes' : 'No' }, width: 20 },
32
33
  { name: 'default_child_block_type_id' , sort: 'default_child_block_type_id' , show: false , bulk_edit: false, nice_name: 'Default Child Block Type' , type: 'select' , value: function(bt) { return bt.default_child_block_type_id; }, width: 400, options_url: '/admin/block-types/options' },
33
34
  { name: 'render_function' , sort: 'render_function' , show: false , bulk_edit: false, nice_name: 'Render Function' , type: 'textarea' , value: function(bt) { return bt.render_function; }, width: 800, height: 200 },
@@ -2,37 +2,73 @@
2
2
  store_config = @invoice.site.store_config if @invoice
3
3
  u = @logged_in_user
4
4
  %>
5
- <div id='my_account'>
6
- <h1>My Account</h1>
7
- <p><div id='user_<%= @user.id %>_first_name' ></div></p>
8
- <p><div id='user_<%= @user.id %>_last_name' ></div></p>
9
- <p><div id='user_<%= @user.id %>_email' ></div></p>
10
- <p><div id='user_<%= @user.id %>_phone' ></div></p>
11
- <div id='message2'></div>
12
5
 
13
- <% if @site.use_store && store_config %>
14
- <h2>Billing</h2>
15
- <p id='card_details'>
16
- <% if u.card_brand && u.card_last4 %>You have a <%= u.card_brand %> ending in <%= u.card_last4 %> on file.<% else %>You have no card on file.<% end %>
17
- <a href='#' onclick="toggle_stripe_form();" />edit</a>
18
- </p>
19
- <form action='' method='post' id='stripe_form' class='stripe_form'>
20
- <div class='card_number_container'><input id='card_number' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' placeholder='Card number' /><div class='svg icon' style='width:30px;height:30px'><svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M2.00585866,0 C0.898053512,0 0,0.900176167 0,1.99201702 L0,9.00798298 C0,10.1081436 0.897060126,11 2.00585866,11 L11.9941413,11 C13.1019465,11 14,10.0998238 14,9.00798298 L14,1.99201702 C14,0.891856397 13.1029399,0 11.9941413,0 L2.00585866,0 Z M2.00247329,1 C1.44882258,1 1,1.4463114 1,1.99754465 L1,9.00245535 C1,9.55338405 1.45576096,10 2.00247329,10 L11.9975267,10 C12.5511774,10 13,9.5536886 13,9.00245535 L13,1.99754465 C13,1.44661595 12.544239,1 11.9975267,1 L2.00247329,1 Z M1,3 L1,5 L13,5 L13,3 L1,3 Z M11,8 L11,9 L12,9 L12,8 L11,8 Z M9,8 L9,9 L10,9 L10,8 L9,8 Z M9,8" style="fill:#3b6faa" transform="translate(8,10)"></g></svg></div></div>
21
- <div class='card_exp_container' ><input id='card_exp' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' placeholder='MM / YY' x-autocompletetype='off' autocompletetype'=off' /><div class='svg icon' style='width:30px;height:30px'><svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M2.0085302,1 C0.899249601,1 0,1.90017617 0,2.99201702 L0,10.007983 C0,11.1081436 0.901950359,12 2.0085302,12 L9.9914698,12 C11.1007504,12 12,11.0998238 12,10.007983 L12,2.99201702 C12,1.8918564 11.0980496,1 9.9914698,1 L2.0085302,1 Z M1.99539757,4 C1.44565467,4 1,4.43788135 1,5.00292933 L1,9.99707067 C1,10.5509732 1.4556644,11 1.99539757,11 L10.0046024,11 C10.5543453,11 11,10.5621186 11,9.99707067 L11,5.00292933 C11,4.44902676 10.5443356,4 10.0046024,4 L1.99539757,4 Z M3,1 L3,2 L4,2 L4,1 L3,1 Z M8,1 L8,2 L9,2 L9,1 L8,1 Z M3,0 L3,1 L4,1 L4,0 L3,0 Z M8,0 L8,1 L9,1 L9,0 L8,0 Z M8,0" style="fill:#3b6faa" transform="translate(8,9)"></g></svg></div></div>
22
- <div class='card_cvc_container' ><input id='card_cvc' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' placeholder='CVC' maxlength='4' /><div class='svg icon' style='width:30px;height:30px'><svg version="1.1" viewBox="0 0 30 30" width="30" height="30" focusable="false"><g fill-rule="evenodd"><path d="M8.8,4 C8.8,1.79086089 7.76640339,4.18628304e-07 5.5,0 C3.23359661,-4.1480896e-07 2.2,1.79086089 2.2,4 L3.2,4 C3.2,2.34314567 3.81102123,0.999999681 5.5,1 C7.18897877,1.00000032 7.80000001,2.34314567 7.80000001,4 L8.8,4 Z M1.99201702,4 C0.891856397,4 0,4.88670635 0,5.99810135 L0,10.0018986 C0,11.1054196 0.900176167,12 1.99201702,12 L9.00798298,12 C10.1081436,12 11,11.1132936 11,10.0018986 L11,5.99810135 C11,4.89458045 10.0998238,4 9.00798298,4 L1.99201702,4 Z M1.99754465,5 C1.44661595,5 1,5.45097518 1,5.99077797 L1,10.009222 C1,10.5564136 1.4463114,11 1.99754465,11 L9.00245535,11 C9.55338405,11 10,10.5490248 10,10.009222 L10,5.99077797 C10,5.44358641 9.5536886,5 9.00245535,5 L1.99754465,5 Z M1.99754465,5" style="fill:#3b6faa" transform="translate(9,9)"></g></svg></div></div>
23
- <div class='card_name_container' ><input id='card_name' type='text' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='on' placeholder='Name on card' /></div>
24
- <div class='card_zip_container' ><input id='card_zip' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='on' placeholder='Zip code' /></div>
25
- <div id='message'></div>
26
- <p class='payment_controls'><input type='submit' class='btn' id='save_payment_btn' value='Save' /></p>
27
- </form>
28
- <% end %>
29
-
30
- <p>
31
- <input type='button' value='Reset Password' class='btn' onclick="reset_user_password();" />
32
- <% if @site.use_store && store_config %>
33
- <input type='button' value='Invoice History' class='btn' onclick="window.location='/my-account/invoices';" />
6
+ <div id="caboose-my-account">
7
+ <h2>My Account</h2>
8
+ <div class="grid-row">
9
+ <div class="<% if @site.use_store %>unit1of2 left<% else %>unit1of1<% end %>">
10
+ <div class="card-form-wrapper address">
11
+ <h4 class="title">Account Information</h4>
12
+ <div class="input-holder"><div id='user_<%= @user.id %>_first_name' ></div></div>
13
+ <div class="input-holder"><div id='user_<%= @user.id %>_last_name' ></div></div>
14
+ <div class="input-holder"><div id='user_<%= @user.id %>_email' ></div></div>
15
+ <div class="input-holder"><div id='user_<%= @user.id %>_phone' ></div></div>
16
+ <div id='message2'></div>
17
+ <p class="buttons">
18
+ <a href="#" title='Reset Password' class='btn' id="reset-password-link">Reset Password</a>
19
+ <% if @site.use_store && store_config %>
20
+ <a href="/my-account/invoices" title='Invoice History' class='btn'>Invoice History</a>
21
+ <% end %>
22
+ </p>
23
+ </div>
24
+ </div>
25
+ <% if @site.use_store && store_config %>
26
+ <div class="unit1of2 right">
27
+ <div class="card-form-wrapper">
28
+ <h4 class="title">Billing</h4>
29
+ <p id='card_details'>
30
+ <% if u.card_brand && u.card_last4 %>
31
+ You have a <%= u.card_brand %> ending in <%= u.card_last4 %> on file.
32
+ <% else %>
33
+ You have no card on file.
34
+ <% end %>
35
+ <a href='#' class='edit-card' id="toggle-stripe-form" />edit</a>
36
+ </p>
37
+ <form action='' method='post' id='stripe_form' class='stripe_form form'>
38
+ <div id="card-wrapper"></div>
39
+ <div class="row clearfix">
40
+ <div class="field">
41
+ <label for="number">Card Number</label>
42
+ <input id='card_number' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' />
43
+ </div>
44
+ </div>
45
+ <div class="row clearfix">
46
+ <div class="field">
47
+ <label for="card_name">Name</label>
48
+ <input id='card_name' type='text' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='on' placeholder='Name on card' value="<%= @user.first_name %> <%= @user.last_name %>" />
49
+ </div>
50
+ </div>
51
+ <div class="row clearfix">
52
+ <div class="field col-3">
53
+ <label for="card_exp">Expiry</label>
54
+ <input id='card_exp' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' placeholder='MM / YYYY' x-autocompletetype='off' autocompletetype='off' />
55
+ </div>
56
+ <div class="field col-3">
57
+ <label for="cvc">CVC</label>
58
+ <input id='card_cvc' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='off' maxlength='4' />
59
+ </div>
60
+ <div class="field col-3">
61
+ <label for="card_zip">ZIP</label>
62
+ <input id='card_zip' type='tel' autocomplete='off' autocorrect='off' spellcheck='off' autocapitalize='on' />
63
+ </div>
64
+ </div>
65
+ <p class='payment_controls'><a href="#" type='submit' class='btn' id='save_payment_btn'>Save</a></p>
66
+ </form>
67
+ <div id='message'></div>
68
+ </div>
69
+ </div>
34
70
  <% end %>
35
- </p>
71
+ </div>
36
72
  </div>
37
73
 
38
74
  <% content_for :caboose_js do %>
@@ -40,6 +76,7 @@ u = @logged_in_user
40
76
  <%= javascript_include_tag 'caboose/model/all' %>
41
77
  <%= javascript_include_tag 'caboose/united_states' %>
42
78
  <%= javascript_include_tag 'caboose/jquery.payment' %>
79
+ <%= javascript_include_tag 'caboose/card' %>
43
80
  <script type='text/javascript'>
44
81
 
45
82
  $(document).ready(function() {
@@ -61,28 +98,69 @@ $(document).ready(function() {
61
98
  $('#user_<%= @user.id %>_phone' ).css('width', '400px');
62
99
  }
63
100
  });
101
+
102
+ $("#reset-password-link").click(function(event) {
103
+ event.preventDefault();
104
+ reset_user_password();
105
+ });
64
106
 
65
107
  <% if @site.use_store && store_config %>
66
- $('#stripe_form').submit(function(e) {
108
+ $('#save_payment_btn').click(function(e) {
67
109
  e.preventDefault();
68
110
  update_card();
69
111
  return false;
70
112
  });
71
-
72
- $('#stripe_form .card_number_container input').payment('formatCardNumber');
73
- $('#stripe_form .card_exp_container input').payment('formatCardExpiry');
74
- $('#stripe_form .card_cvc_container input').payment('formatCardCVC');
75
- $('#stripe_form').hide();
113
+ $("#toggle-stripe-form").click(function(event) {
114
+ event.preventDefault();
115
+ toggle_stripe_form();
116
+ });
117
+ $('#card_exp').payment('formatCardExpiry');
118
+ $('#card_cvc').payment('formatCardCVC');
76
119
  <% end %>
77
120
  });
78
121
 
79
122
  <% if @site.use_store && store_config %>
123
+
124
+ function show_card() {
125
+ var card = new Card({
126
+ form: '#stripe_form',
127
+ container: '#card-wrapper',
128
+ formSelectors: {
129
+ numberInput: 'input#card_number',
130
+ expiryInput: 'input#card_exp',
131
+ cvcInput: 'input#card_cvc',
132
+ nameInput: 'input#card_name'
133
+ },
134
+ width: 250,
135
+ formatting: true,
136
+ messages: {
137
+ validDate: 'valid\ndate',
138
+ monthYear: 'mm/yyyy',
139
+ },
140
+ <% if !@user.card_last4.blank? %>
141
+ placeholders: {
142
+ number: '**** **** **** <%= @user.card_last4 %>',
143
+ name: '<%= @user.first_name %> <%= @user.last_name %>',
144
+ expiry: '<%= @user.card_exp_month %>/<%= @user.card_exp_year %>'
145
+ }
146
+ <% end %>
147
+ });
148
+ <% if !@user.card_brand.blank? %>
149
+ $(".jp-card").addClass("jp-card-<%= @user.card_brand.gsub('American Express','amex').downcase %>").addClass("jp-card-identified");
150
+ <% end %>
151
+ }
152
+
80
153
  function toggle_stripe_form()
81
154
  {
82
- if ($('#stripe_form').is(':visible'))
155
+ if ($('#stripe_form').is(':visible')) {
83
156
  $('#stripe_form').hide();
84
- else
85
- $('#stripe_form').show();
157
+ $("#card-wrapper").hide();
158
+ }
159
+ else {
160
+ $('#stripe_form').show();
161
+ $("#card-wrapper").show();
162
+ show_card();
163
+ }
86
164
  }
87
165
 
88
166
  function update_card()
@@ -103,14 +181,14 @@ function update_card()
103
181
  if (!$.payment.validateCardCVC(info.cvc)) error = "Invalid CVC.";
104
182
  if (error) { $('#message').html("<p class='note error'>" + error + "</p>"); return; }
105
183
 
106
- $('#save_payment_btn').attr('disabled', 'true').val('Saving card...');
184
+ $('#save_payment_btn').addClass('disabled').text('Saving card...');
107
185
  Stripe.setPublishableKey(<%= raw Caboose.json(store_config.stripe_publishable_key) %>);
108
186
  Stripe.card.createToken(info, function(status, resp) {
109
187
  if (resp.error)
110
188
  {
111
- $('#save_payment_btn').attr('disabled', 'false').val('Save Payment Method');
189
+ $('#save_payment_btn').removeClass('disabled').text('Save');
112
190
  $('#message').html("<p class='note error'>" + resp.error.message + "</p>");
113
- }
191
+ }
114
192
  else
115
193
  {
116
194
  $.ajax({
@@ -131,20 +209,20 @@ function reset_user_password(pass1, pass2)
131
209
  {
132
210
  if (!pass1)
133
211
  {
134
- var p = $('<p/>').addClass('note warning')
212
+ var p = $('<p/>').addClass('note warning reset-password')
135
213
  .append("Please enter your password:<br /><br />")
136
214
  .append($('<input/>').attr('type', 'password').attr('id', 'pass1').css('width', '200px')).append(' ')
137
- .append($('<input/>').attr('type', 'button').val('Continue').click(function(e) { reset_user_password($('#pass1').val()); }))
215
+ .append($('<a/>').attr('class','btn alternate').attr('href','#').text('Continue').click(function(e) { reset_user_password($('#pass1').val()); }))
138
216
  .append("<br /><br />Passwords must be 8 characters long.");
139
217
  $('#message2').empty().append(p);
140
218
  return;
141
219
  }
142
220
  if (!pass2)
143
221
  {
144
- var p = $('<p/>').addClass('note warning')
222
+ var p = $('<p/>').addClass('note warning reset-password')
145
223
  .append("Please enter it again to confirm:<br /><br />")
146
224
  .append($('<input/>').attr('type', 'password').attr('id', 'pass2').css('width', '200px')).append(' ')
147
- .append($('<input/>').attr('type', 'button').val('Continue').click(function(e) { reset_user_password(pass1, $('#pass2').val()); }))
225
+ .append($('<a/>').attr('href', '#').addClass('btn alternate').text('Continue').click(function(e) { reset_user_password(pass1, $('#pass2').val()); }))
148
226
  .append("<br /><br />Passwords must be 8 characters long.");
149
227
  $('#message2').empty().append(p);
150
228
  return;
@@ -171,21 +249,4 @@ function reset_user_password(pass1, pass2)
171
249
  <% end %>
172
250
  <%= content_for :caboose_css do %>
173
251
  <%= stylesheet_link_tag "caboose/my_account", :media => "all" %>
174
- <style type='text/css'>
175
-
176
- .stripe_form { width: 100%; }
177
- .stripe_form .card_number_container { position: relative; width: 100%; } .stripe_form .card_number_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 1px; }
178
- .stripe_form .card_exp_container { position: relative; width: 50% !important; float: left; } .stripe_form .card_exp_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 1px; }
179
- .stripe_form .card_cvc_container { position: relative; width: 50%; float: left; } .stripe_form .card_cvc_container input { padding-left: 30px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 0px 0px; }
180
- .stripe_form .card_name_container { position: relative; width: 50%; float: left; } .stripe_form .card_name_container input { padding-left: 10px; height: 37px !important; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 0px 1px 1px; }
181
- .stripe_form .card_zip_container { position: relative; width: 50%; float: left; margin-bottom: 4px; } .stripe_form .card_zip_container input { padding-left: 10px; height: 37px; font-size: 15px; width: 100%; border-color: #b9b9b9; border-style: solid; border-width: 1px 1px 1px 0px; }
182
-
183
- .stripe_form .card_number_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
184
- .stripe_form .card_exp_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
185
- .stripe_form .card_cvc_container .icon { position: absolute; top: 3px; left: 1px; transform-origin: 50% 50% 0; pointer-events: none; }
186
-
187
- .stripe_form .note { width: 100%; margin-bottom: 10px !important; text-align: center; }
188
- .stripe_form .payment_controls { clear: left; margin-top: 4px !important; }
189
-
190
- </style>
191
- <% end %>
252
+ <% end %>