effective_cpd 0.0.1

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 (66) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +117 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/config/effective_cpd_manifest.js +2 -0
  6. data/app/assets/javascripts/effective_cpd.js +2 -0
  7. data/app/assets/javascripts/effective_cpd/activities.js +49 -0
  8. data/app/assets/javascripts/effective_cpd/activities_new.js +21 -0
  9. data/app/assets/stylesheets/effective_cpd.scss +1 -0
  10. data/app/assets/stylesheets/effective_cpd/_activities.scss +19 -0
  11. data/app/controllers/admin/cpd_activities_controller.rb +13 -0
  12. data/app/controllers/admin/cpd_categories_controller.rb +13 -0
  13. data/app/controllers/admin/cpd_cycles_controller.rb +13 -0
  14. data/app/controllers/admin/cpd_rules_controller.rb +13 -0
  15. data/app/controllers/admin/cpd_statements_controller.rb +13 -0
  16. data/app/controllers/effective/cpd_cycles_controller.rb +19 -0
  17. data/app/controllers/effective/cpd_statement_activities_controller.rb +27 -0
  18. data/app/controllers/effective/cpd_statements_controller.rb +71 -0
  19. data/app/datatables/admin/effective_cpd_activities_datatable.rb +31 -0
  20. data/app/datatables/admin/effective_cpd_categories_datatable.rb +24 -0
  21. data/app/datatables/admin/effective_cpd_cycles_datatable.rb +22 -0
  22. data/app/datatables/admin/effective_cpd_rules_datatable.rb +43 -0
  23. data/app/datatables/admin/effective_cpd_statements_datatable.rb +30 -0
  24. data/app/datatables/effective_cpd_datatable.rb +30 -0
  25. data/app/datatables/effective_cpd_statements_datatable.rb +23 -0
  26. data/app/helpers/effective_cpd_helper.rb +37 -0
  27. data/app/mailers/effective/cpd_mailer.rb +7 -0
  28. data/app/models/effective/cpd_activity.rb +41 -0
  29. data/app/models/effective/cpd_category.rb +35 -0
  30. data/app/models/effective/cpd_cycle.rb +113 -0
  31. data/app/models/effective/cpd_rule.rb +108 -0
  32. data/app/models/effective/cpd_scorer.rb +158 -0
  33. data/app/models/effective/cpd_statement.rb +95 -0
  34. data/app/models/effective/cpd_statement_activity.rb +78 -0
  35. data/app/views/admin/cpd_activities/_form.html.haml +20 -0
  36. data/app/views/admin/cpd_categories/_form.html.haml +21 -0
  37. data/app/views/admin/cpd_categories/_form_cpd_category.html.haml +5 -0
  38. data/app/views/admin/cpd_cycles/_form.html.haml +17 -0
  39. data/app/views/admin/cpd_cycles/_form_content.html.haml +32 -0
  40. data/app/views/admin/cpd_cycles/_form_cpd_cycle.html.haml +21 -0
  41. data/app/views/admin/cpd_cycles/_form_cpd_rules.html.haml +56 -0
  42. data/app/views/admin/cpd_statements/_form.html.haml +6 -0
  43. data/app/views/effective/cpd_statement_activities/_form.html.haml +70 -0
  44. data/app/views/effective/cpd_statements/_activities.html.haml +64 -0
  45. data/app/views/effective/cpd_statements/_activities_new.html.haml +39 -0
  46. data/app/views/effective/cpd_statements/_agreements.html.haml +6 -0
  47. data/app/views/effective/cpd_statements/_cpd_statement.html.haml +5 -0
  48. data/app/views/effective/cpd_statements/_layout.html.haml +37 -0
  49. data/app/views/effective/cpd_statements/_summary.html.haml +36 -0
  50. data/app/views/effective/cpd_statements/activities.html.haml +25 -0
  51. data/app/views/effective/cpd_statements/agreements.html.haml +14 -0
  52. data/app/views/effective/cpd_statements/complete.html.haml +13 -0
  53. data/app/views/effective/cpd_statements/start.html.haml +13 -0
  54. data/app/views/effective/cpd_statements/submit.html.haml +20 -0
  55. data/app/views/layouts/effective_cpd_mailer_layout.html.haml +7 -0
  56. data/config/effective_cpd.rb +29 -0
  57. data/config/routes.rb +28 -0
  58. data/db/migrate/01_create_effective_cpd.rb.erb +98 -0
  59. data/db/seeds.rb +472 -0
  60. data/lib/effective_cpd.rb +18 -0
  61. data/lib/effective_cpd/engine.rb +11 -0
  62. data/lib/effective_cpd/version.rb +3 -0
  63. data/lib/generators/effective_cpd/install_generator.rb +46 -0
  64. data/lib/generators/templates/effective_cpd_mailer_preview.rb +4 -0
  65. data/lib/tasks/effective_cpd_tasks.rake +6 -0
  66. metadata +233 -0
@@ -0,0 +1,21 @@
1
+ = tabs do
2
+ = tab 'Category' do
3
+ - if cpd_category.persisted?
4
+ .alert.alert-warning
5
+ Changes to categories and activities will be displayed in all #{cpd_cycles_label}.
6
+
7
+ = render 'admin/cpd_categories/form_cpd_category', cpd_category: cpd_category
8
+
9
+ - if cpd_category.persisted?
10
+ %h2 Activities
11
+ %p
12
+ After adding an activity here, please visit any existing
13
+ = link_to(cpd_cycles_label.titleize + ' Settings', effective_cpd.admin_cpd_cycles_path)
14
+ pages and build a rule before it will be displayed.
15
+
16
+ - datatable = Admin::EffectiveCpdActivitiesDatatable.new(cpd_category_id: cpd_category.id)
17
+ = render_datatable(datatable, inline: true, simple: true)
18
+
19
+ - if cpd_category.persisted? && cpd_category.respond_to?(:log_changes_datatable)
20
+ = tab 'Logs' do
21
+ = render_datatable(cpd_category.log_changes_datatable)
@@ -0,0 +1,5 @@
1
+ = effective_form_with(model: [:admin, cpd_category], engine: true) do |f|
2
+ = f.text_field :title
3
+ = f.rich_text_area :body
4
+
5
+ = effective_submit(f)
@@ -0,0 +1,17 @@
1
+ = tabs do
2
+ = tab 'Cycle' do
3
+ = render 'admin/cpd_cycles/form_cpd_cycle', cpd_cycle: cpd_cycle
4
+
5
+ - if cpd_cycle.persisted?
6
+ = tab 'Content' do
7
+ = render 'admin/cpd_cycles/form_content', cpd_cycle: cpd_cycle
8
+
9
+ = tab 'Category and Activity Rules' do
10
+ = tabs do
11
+ - Effective::CpdCategory.deep.sorted.each do |cpd_category|
12
+ = tab(cpd_category.to_s) do
13
+ = render 'admin/cpd_cycles/form_cpd_rules', cpd_cycle: cpd_cycle, cpd_category: cpd_category
14
+
15
+ - if cpd_cycle.respond_to?(:log_changes_datatable)
16
+ = tab 'Logs' do
17
+ = render_datatable(cpd_cycle.log_changes_datatable)
@@ -0,0 +1,32 @@
1
+ = effective_form_with(model: [:admin, cpd_cycle], engine: true) do |f|
2
+ .card.mb-4
3
+ .card-body
4
+ %h5.card-title All Steps Content
5
+ = f.rich_text_area :all_steps_content, label: false, hint: 'displayed on all statement steps'
6
+
7
+ .card.mb-4
8
+ .card-body
9
+ %h5.card-title Start Step
10
+ = f.rich_text_area :start_content, label: false, hint: 'displayed on the start step only'
11
+
12
+ .card.mb-4
13
+ .card-body
14
+ %h5.card-title Activities Step
15
+ = f.rich_text_area :activities_content, label: false, hint: 'displayed on the activities step only'
16
+
17
+ .card.mb-4
18
+ .card-body
19
+ %h5.card-title Agreements Step
20
+ = f.rich_text_area :agreements_content, label: false, hint: 'displayed on the agreements step only'
21
+
22
+ .card.mb-4
23
+ .card-body
24
+ %h5.card-title Submit Step
25
+ = f.rich_text_area :submit_content, label: false, hint: 'displayed on the submit step only'
26
+
27
+ .card.mb-4
28
+ .card-body
29
+ %h5.card-title Complete Step
30
+ = f.rich_text_area :complete_content, label: false, hint: 'displayed on the complete step only'
31
+
32
+ = f.submit
@@ -0,0 +1,21 @@
1
+ = effective_form_with(model: [:admin, cpd_cycle], engine: true) do |f|
2
+ = f.text_field :title,
3
+ hint: "The title of this #{cpd_cycle_label}. Something like #{Time.zone.now.year} Continuing Professional Development"
4
+
5
+ = f.date_field :start_at,
6
+ hint: "The first date statements may be submited for this #{cpd_cycle_label}"
7
+
8
+ = f.date_field :end_at,
9
+ hint: "The last date statements may be created for this #{cpd_cycle_label}. leave blank for no end date."
10
+
11
+ - if f.object.new_record?
12
+ - latest_cycle = Effective::CpdCycle.latest_cycle
13
+
14
+ - if latest_cycle.present?
15
+ = f.static_field :continue_from, value: latest_cycle,
16
+ hint: "The next #{cpd_cycle_label} will be carried forward from last one. Please make sure this #{cpd_cycle_label} is the most recent one."
17
+
18
+ = f.submit("Save and Create Next #{cpd_cycle_label.titleize}")
19
+
20
+ - if f.object.persisted?
21
+ = f.submit
@@ -0,0 +1,56 @@
1
+ - edit_path = effective_cpd.edit_admin_cpd_category_path(cpd_category)
2
+
3
+ = effective_form_with(model: [:admin, cpd_cycle], engine: true) do |f|
4
+ %h2= cpd_category
5
+ %p= cpd_category.body
6
+ %p= link_to 'Edit Category', edit_path, target: '_blank'
7
+
8
+ = f.fields_for :cpd_rules, cpd_cycle.rule_for(cpd_category) do |fc|
9
+ = fc.number_field :max_credits_per_cycle,
10
+ label: "Max #{cpd_credits_label} per #{cpd_cycle_label}",
11
+ hint: "The maximum number of #{cpd_credits_label} that may be earned in this category for this #{cpd_cycle_label}. Leave blank for no limit."
12
+
13
+ = fc.text_field :credit_description,
14
+ hint: "A simple description of the maximum #{cpd_credits_label} and carry forward policy of activities for this category"
15
+
16
+ = fc.check_box :unavailable, label: "Unavailable in this #{cpd_cycle_label}"
17
+
18
+ = f.submit
19
+
20
+ = effective_form_with(model: [:admin, cpd_cycle], engine: true) do |f|
21
+ %h2 Activities
22
+ - rules = cpd_category.cpd_activities.map { |activity| cpd_cycle.rule_for(activity) }
23
+
24
+ = f.fields_for :cpd_rules, rules do |fa|
25
+ - activity = fa.object.ruleable
26
+
27
+ = card do
28
+ .row
29
+ .col
30
+ %h5.card-title= activity
31
+ - if activity.body.present?
32
+ %p= activity.body
33
+
34
+ %p= link_to 'Edit Activity', edit_path, target: '_blank'
35
+
36
+ = f.static_field :amount_label, value: activity.amount_label.presence || '-'
37
+ = f.static_field :amount2_label, value: activity.amount2_label.presence || '-'
38
+ = f.static_field :requires_upload_file, value: (activity.requires_upload_file ? 'Yes' : '-')
39
+
40
+ .col
41
+ = fa.text_field :formula, hint: cpd_rule_formula_hint(activity)
42
+
43
+ = fa.text_field :credit_description, label: "#{cpd_credits_label.titleize} description",
44
+ hint: "A simple description of the formula and its #{cpd_credits_label} calculation"
45
+
46
+ = fa.number_field :max_credits_per_cycle,
47
+ label: "Max #{cpd_credits_label} per #{cpd_cycle_label}",
48
+ hint: 'leave blank for no limit'
49
+
50
+ = fa.number_field :max_cycles_can_carry_forward,
51
+ label: "Max #{cpd_cycles_label} can carry forward",
52
+ hint: "leave blank for no limit"
53
+
54
+ = fa.check_box :unavailable, label: "Unavailable in this #{cpd_cycle_label}"
55
+
56
+ = f.submit
@@ -0,0 +1,6 @@
1
+ = tabs do
2
+ = tab 'Statement' do
3
+ = render('effective/cpd_statements/cpd_statement', cpd_statement: cpd_statement)
4
+
5
+ = tab 'Logs' do
6
+ = render_inline_datatable(cpd_statement.log_changes_datatable)
@@ -0,0 +1,70 @@
1
+ - url = (cpd_statement_activity.persisted? ? effective_cpd.cpd_statement_cpd_statement_activity_path(cpd_statement_activity.cpd_statement, cpd_statement_activity) : effective_cpd.cpd_statement_cpd_statement_activities_path(cpd_statement_activity.cpd_statement))
2
+ - readonly = cpd_statement_activity.locked? || local_assigns[:readonly]
3
+
4
+ = effective_form_with(model: cpd_statement_activity, url: (readonly ? '#' : url), remote: true, class: 'cpd-statement-activity-form') do |f|
5
+ - statement = cpd_statement_activity.cpd_statement
6
+ - activity = cpd_statement_activity.cpd_activity
7
+ - rule = statement.cpd_cycle.rule_for(activity)
8
+
9
+ %h3= activity
10
+
11
+ - if activity.body.present?
12
+ = activity.body
13
+
14
+ - if cpd_statement_activity.is_carry_over? && (current_user.id == cpd_statement_activity.cpd_statement.user_id)
15
+ .alert.alert-warning
16
+ This activity is read-only because it was carried forward from
17
+ = cpd_statement_activity.original.cpd_statement.cpd_cycle
18
+
19
+ .row.my-3
20
+ .col-8
21
+ %strong #{cpd_credits_label.titleize} Calculation
22
+ %br
23
+ = rule.credit_description
24
+
25
+ .col-2.text-center
26
+ - if f.object.persisted?
27
+ %strong= cpd_credits_label.titleize
28
+ %br
29
+ - if f.object.reduced_messages.present?
30
+ %span{title: f.object.reduced_messages.values.join("\n\n")}= "#{f.object.score} *"
31
+ - else
32
+ = f.object.score.to_i
33
+
34
+ .col-2.text-center
35
+ - if f.object.persisted?
36
+ %strong Carry Forward
37
+ %br
38
+ = f.object.carry_forward.to_i
39
+
40
+ .row
41
+ .col
42
+ - if activity.amount_label.present?
43
+ = f.number_field :amount, label: activity.amount_label.titleize, required: true, readonly: readonly, disabled: readonly
44
+
45
+ - if activity.amount2_label.present?
46
+ = f.number_field :amount2, label: activity.amount2_label.titleize, required: true, readonly: readonly, disabled: readonly
47
+
48
+ - if activity.amount_label.blank? && activity.amount2_label.blank?
49
+ = f.hidden_field :amount, value: 1
50
+ %p One (1) #{activity}
51
+
52
+ - unless readonly && f.object.files.blank?
53
+ = f.file_field :files, label: 'Supporting Documents', required: activity.requires_upload_file?, disabled: readonly
54
+
55
+ .col
56
+ = f.text_area :description, placeholder: 'Please provide any additional information about this activity', readonly: readonly, disabled: readonly
57
+
58
+ - unless readonly
59
+ = f.hidden_field :cpd_category_id
60
+ = f.hidden_field :cpd_activity_id
61
+
62
+ = f.submit do
63
+ = f.save 'Save Activity'
64
+
65
+ %div{style: 'position: absolute; left: 0;'}
66
+ - if f.object.new_record?
67
+ = link_to('Back', '#', class: 'btn btn-secondary', 'data-cpd-back-activity': true)
68
+ - else
69
+ - url = effective_cpd.cpd_statement_cpd_statement_activity_path(statement, cpd_statement_activity)
70
+ = link_to('Delete', url, class: 'btn btn-danger', 'data-confirm': "Really delete?", 'data-method': :delete)
@@ -0,0 +1,64 @@
1
+ .cpd-statement-activities
2
+ .row
3
+ .col-8
4
+ .col-2.score
5
+ %strong= cpd_credits_label.titleize
6
+ .col-2.carry-forward
7
+ %strong Carry Forward
8
+
9
+ - effective_cpd_categories.each do |category|
10
+ - statement_activities = cpd_statement.cpd_statement_activities.select { |a| a.cpd_category_id == category.id }
11
+ - next if statement_activities.blank?
12
+
13
+ - rule = cpd_statement.cpd_cycle.rule_for(category)
14
+
15
+ .statement-activity-category
16
+ %h3
17
+ #{category}
18
+ %small
19
+ = cpd_statement.score_per_category[category.id].to_i
20
+ - if rule.max_credits_per_cycle.present?
21
+ = '/'
22
+ = rule.max_credits_per_cycle
23
+
24
+ .progress.my-2
25
+ - valuenow = cpd_statement.score_per_category[category.id]
26
+ - valuemax = (rule.max_credits_per_cycle || 1)
27
+ - width = ((valuenow * 100.0) / valuemax)
28
+
29
+ .progress-bar{role: 'progressbar', style: "width: #{width}%", 'aria-valuenow': valuenow, 'aria-valuemin': 0, 'aria-valuemax': valuemax}
30
+
31
+ - statement_activities.each do |statement_activity|
32
+ .statement-activity.mb-3
33
+ .statement-activity-content.row
34
+ .col-8
35
+ = link_to('#', 'data-cpd-edit-activity': true) do
36
+ = icon('plus-circle', class: 'small-1')
37
+ = statement_activity.cpd_activity
38
+ - if statement_activity.is_carry_over?
39
+ %br
40
+ %small carried forward from #{statement_activity.original_cycle}
41
+
42
+ .col-2.score
43
+ - if statement_activity.reduced_messages.present?
44
+ %span{title: statement_activity.reduced_messages.values.join("\n\n")}= "#{statement_activity.score} *"
45
+ - else
46
+ = statement_activity.score.to_i
47
+
48
+ .col-2.carry-forward
49
+ = statement_activity.carry_forward.to_i
50
+
51
+ .statement-activity-form.row{style: 'display: none;'}
52
+ .col
53
+ .border.px-3
54
+ = render('effective/cpd_statement_activities/form', cpd_statement_activity: statement_activity, readonly: local_assigns[:readonly])
55
+
56
+ %hr
57
+
58
+ .row
59
+ .col-8
60
+ %h4 Total #{cpd_credits_label} in statement
61
+ .col-2.score
62
+ %h4= cpd_statement.score.to_i
63
+ .col-2.carry-forward
64
+ %h4= cpd_statement.carry_forward.to_i
@@ -0,0 +1,39 @@
1
+ = vertical_tabs do
2
+ .statement-activity-content.tab-pane
3
+ -# The javascript will load the .statement-activity-form content into here
4
+
5
+ - effective_cpd_categories.each do |category|
6
+ - rule = cpd_statement.cpd_cycle.rule_for(category)
7
+ - next if rule.unavailable?
8
+
9
+ = tab(category) do
10
+ %h3
11
+ #{category}
12
+ %small
13
+ = cpd_statement.score_per_category[category.id].to_i
14
+ - if rule.max_credits_per_cycle.present?
15
+ = '/'
16
+ = rule.max_credits_per_cycle
17
+
18
+ .mb-3
19
+ %strong Description
20
+ = category.body
21
+
22
+ .mb-3
23
+ %strong #{cpd_credits_label.titleize} Calculation
24
+ %br
25
+ = rule.credit_description
26
+
27
+ %div
28
+ %strong Select an Activity to Continue
29
+
30
+ %ol
31
+ - category.cpd_activities.each do |activity|
32
+ - next if cpd_statement.cpd_cycle.rule_for(activity).unavailable?
33
+
34
+ %li
35
+ = link_to(activity, '#', 'data-cpd-show-activity': true)
36
+
37
+ .statement-activity-form{style: 'display: none;'}
38
+ - cpd_statement_activity = cpd_statement.cpd_statement_activities.new(cpd_category: category, cpd_activity: activity)
39
+ = render('effective/cpd_statement_activities/form', cpd_statement_activity: cpd_statement_activity)
@@ -0,0 +1,6 @@
1
+ %h2 Agreements
2
+ = f.check_box :confirm_read, label: "Yes, I have read the above content and agreements"
3
+ = f.check_box :confirm_factual, label: "Yes, I declare all provided information to be factual and complete"
4
+
5
+ %h2 Resume
6
+ = f.file_field :files, label: 'Attach resume', hint: 'Please attach your resume or other CPD related documents'
@@ -0,0 +1,5 @@
1
+ = card(cpd_statement.cpd_cycle.to_s + ' Statement') do
2
+ = render('effective/cpd_statements/summary', cpd_statement: cpd_statement)
3
+
4
+ = card('Activities') do
5
+ = render('effective/cpd_statements/activities', cpd_statement: cpd_statement, readonly: true)
@@ -0,0 +1,37 @@
1
+ .row
2
+ .col-3
3
+ = render_wizard_sidebar(resource)
4
+
5
+ - cpd_cycle = resource.cpd_cycle
6
+ - start_at = cpd_cycle.start_at
7
+ - end_at = cpd_cycle.end_at
8
+ - last_3_cycles = Effective::CpdCycle.sorted.where('start_at <= ?', start_at).last(3)
9
+ - last_3_scores = Effective::CpdStatement.where(cpd_cycle: last_3_cycles, user: resource.user).sum(&:score)
10
+
11
+ %table.table.mt-4
12
+ %tbody
13
+ - if end_at.present? && !resource.completed?
14
+ %tr{title: "#{cpd_cycle} is available #{cpd_cycle.available_date}"}
15
+ %td
16
+ %h4= ((end_at - Time.zone.now) / 1.day).to_i
17
+
18
+ %td days left to submit
19
+
20
+ %tr
21
+ %td
22
+ %h4= resource.score.to_i
23
+
24
+ %td
25
+ - if cpd_cycle.required_score.to_i > 0
26
+ #{cpd_credits_label} out of #{cpd_cycle.required_score} required
27
+ - else
28
+ #{cpd_credits_label} in current #{cpd_cycle_label}
29
+
30
+ %tr
31
+ %td
32
+ %h4= last_3_scores.to_i
33
+
34
+ %td #{cpd_credits_label} in last 3 #{cpd_cycles_label} (including this #{cpd_cycle_label})
35
+
36
+ .col-9
37
+ = yield
@@ -0,0 +1,36 @@
1
+ %table.table
2
+ %tbody
3
+ %tr
4
+ %th Name
5
+ %td
6
+ = cpd_statement.user
7
+ %br
8
+ %small= mail_to cpd_statement.user.email
9
+
10
+ - if request.path.start_with?('/admin') && respond_to?(:edit_admin_user_path)
11
+ %tr
12
+ %th User
13
+ %td= link_to(cpd_statement.user, edit_admin_user_path(cpd_statement.user))
14
+
15
+ - if cpd_statement.completed?
16
+ %tr
17
+ %th Completed
18
+ %td= cpd_statement.completed_at.strftime('%F %H:%M')
19
+
20
+ %tr
21
+ %th= cpd_cycle_label.titleize
22
+ %td= cpd_statement.cpd_cycle
23
+ %tr
24
+ %th Total #{cpd_credits_label.titleize}
25
+ %td= cpd_statement.score
26
+ %tr
27
+ %th Carry Forward
28
+ %td= cpd_statement.carry_forward
29
+ %tr
30
+ %th Attachments
31
+ %td
32
+ - if cpd_statement.files.blank?
33
+ None
34
+ - else
35
+ - cpd_statement.files.each do |file|
36
+ %div= link_to(file.filename, url_for(file), target: '_blank')
@@ -0,0 +1,25 @@
1
+ #cpd-statement-activities
2
+ .row
3
+ .col-3
4
+ .col-9
5
+ %h1= resource.cpd_cycle
6
+
7
+ .activities-index
8
+ = render('layout') do
9
+ - if resource.cpd_cycle.all_steps_content.present?
10
+ .mb-2= resource.cpd_cycle.all_steps_content
11
+
12
+ - if resource.cpd_cycle.activities_content.present?
13
+ .mb-2= resource.cpd_cycle.activities_content
14
+
15
+ - if resource.cpd_statement_activities.present?
16
+ = render('activities', cpd_statement: resource)
17
+
18
+ .mt-3= link_to 'Add Activity', '#', 'data-cpd-new-activity': true, class: 'btn btn-primary'
19
+
20
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
21
+ = f.hidden_field :current_step
22
+ = f.submit 'Save and Continue', center: true
23
+
24
+ .activities-new{style: 'display: none;'}
25
+ = render('activities_new', cpd_statement: resource)