caboose-cms 0.8.43 → 0.8.44

Sign up to get free protection for your applications and to get access to all the features.
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 %>