effective_classifieds 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +122 -0
  4. data/Rakefile +18 -0
  5. data/app/assets/config/effective_classifieds_manifest.js +3 -0
  6. data/app/assets/javascripts/effective_classifieds/base.js +0 -0
  7. data/app/assets/javascripts/effective_classifieds.js +1 -0
  8. data/app/assets/stylesheets/effective_classifieds/base.scss +0 -0
  9. data/app/assets/stylesheets/effective_classifieds.scss +1 -0
  10. data/app/controllers/admin/classified_submissions_controller.rb +19 -0
  11. data/app/controllers/admin/classifieds_controller.rb +20 -0
  12. data/app/controllers/effective/classified_submissions_controller.rb +31 -0
  13. data/app/controllers/effective/classifieds_controller.rb +53 -0
  14. data/app/datatables/admin/effective_classified_submissions_datatable.rb +22 -0
  15. data/app/datatables/admin/effective_classifieds_datatable.rb +61 -0
  16. data/app/datatables/effective_classified_submissions_datatable.rb +37 -0
  17. data/app/datatables/effective_classifieds_datatable.rb +25 -0
  18. data/app/helpers/effective_classifieds_helper.rb +7 -0
  19. data/app/mailers/effective/classifieds_mailer.rb +22 -0
  20. data/app/models/concerns/effective_classifieds_classified_submission.rb +112 -0
  21. data/app/models/effective/classified.rb +164 -0
  22. data/app/models/effective/classified_submission.rb +7 -0
  23. data/app/views/admin/classifieds/_form.html.haml +12 -0
  24. data/app/views/admin/classifieds/_form_access.html.haml +10 -0
  25. data/app/views/admin/classifieds/_form_classified.html.haml +3 -0
  26. data/app/views/effective/classified_submissions/_classified.haml +12 -0
  27. data/app/views/effective/classified_submissions/_classified_submission.html.haml +8 -0
  28. data/app/views/effective/classified_submissions/_content.html.haml +1 -0
  29. data/app/views/effective/classified_submissions/_dashboard.html.haml +28 -0
  30. data/app/views/effective/classified_submissions/_layout.html.haml +3 -0
  31. data/app/views/effective/classified_submissions/_summary.html.haml +30 -0
  32. data/app/views/effective/classified_submissions/classified.html.haml +17 -0
  33. data/app/views/effective/classified_submissions/start.html.haml +16 -0
  34. data/app/views/effective/classified_submissions/submitted.html.haml +13 -0
  35. data/app/views/effective/classified_submissions/summary.html.haml +8 -0
  36. data/app/views/effective/classifieds/_classified.html.haml +50 -0
  37. data/app/views/effective/classifieds/_dashboard.html.haml +8 -0
  38. data/app/views/effective/classifieds/_fields.html.haml +28 -0
  39. data/app/views/effective/classifieds/_form.html.haml +3 -0
  40. data/app/views/effective/classifieds/_layout.html.haml +1 -0
  41. data/app/views/effective/classifieds/_spacer.html.haml +1 -0
  42. data/app/views/effective/classifieds/index.html.haml +8 -0
  43. data/app/views/effective/classifieds/show.html.haml +8 -0
  44. data/app/views/effective/classifieds_mailer/classified_submitted.html.haml +16 -0
  45. data/app/views/layouts/effective_classifieds_mailer_layout.html.haml +7 -0
  46. data/config/effective_classifieds.rb +45 -0
  47. data/config/routes.rb +24 -0
  48. data/db/migrate/01_create_effective_classifieds.rb.erb +62 -0
  49. data/db/seeds.rb +1 -0
  50. data/lib/effective_classifieds/engine.rb +18 -0
  51. data/lib/effective_classifieds/version.rb +3 -0
  52. data/lib/effective_classifieds.rb +45 -0
  53. data/lib/generators/effective_classifieds/install_generator.rb +31 -0
  54. data/lib/generators/templates/effective_classifieds_mailer_preview.rb +4 -0
  55. data/lib/tasks/effective_classifieds_tasks.rake +8 -0
  56. metadata +251 -0
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Effective
4
+ class Classified < ActiveRecord::Base
5
+ self.table_name = EffectiveClassifieds.classifieds_table_name.to_s
6
+
7
+ attr_accessor :current_user
8
+
9
+ acts_as_slugged
10
+ log_changes if respond_to?(:log_changes)
11
+ acts_as_role_restricted if respond_to?(:acts_as_role_restricted)
12
+
13
+ # This will be the owner of the classified submission
14
+ # Or the admin user that created it
15
+ belongs_to :owner, polymorphic: true
16
+
17
+ # When submitted through the wizard
18
+ belongs_to :classified_submission, polymorphic: true, optional: true
19
+
20
+ has_rich_text :body
21
+
22
+ acts_as_statused(
23
+ :draft, # Initial state
24
+ :submitted, # Once submitted by the classified submission.
25
+ :approved # Exit state. Classified was approved.
26
+ )
27
+
28
+ effective_resource do
29
+ title :string
30
+ category :string
31
+
32
+ organization :string # Or seller
33
+ location :string
34
+
35
+ website :string
36
+ email :string
37
+ phone :string
38
+
39
+ # Logic
40
+ start_on :date
41
+ end_on :date
42
+
43
+ # Acts as Slugged
44
+ slug :string
45
+
46
+ # Acts as Statused
47
+ status :string, permitted: false
48
+ status_steps :text, permitted: false
49
+
50
+ # Access
51
+ roles_mask :integer
52
+ authenticate_user :boolean
53
+
54
+ archived :boolean
55
+
56
+ timestamps
57
+ end
58
+
59
+ scope :sorted, -> { order(:id) }
60
+ scope :deep, -> { with_rich_text_body }
61
+
62
+ scope :upcoming, -> { where(arel_table[:end_on].gt(Time.zone.now)) }
63
+ scope :past, -> { where(arel_table[:end_on].lteq(Time.zone.now)) }
64
+
65
+ scope :unarchived, -> { where(archived: false) }
66
+ scope :archived, -> { where(archived: true) }
67
+
68
+ scope :published, -> {
69
+ approved
70
+ .unarchived
71
+ .where(arel_table[:start_on].lteq(Time.zone.now))
72
+ .where(arel_table[:end_on].gt(Time.zone.now))
73
+ }
74
+
75
+ scope :paginate, -> (page: nil, per_page: nil) {
76
+ page = (page || 1).to_i
77
+ offset = [(page - 1), 0].max * (per_page || EffectiveClassifieds.per_page)
78
+
79
+ limit(per_page).offset(offset)
80
+ }
81
+
82
+ scope :classifieds, -> (user: nil, unpublished: false) {
83
+ scope = all.deep.sorted
84
+
85
+ if defined?(EffectiveRoles) && EffectiveClassifieds.use_effective_roles
86
+ scope = scope.for_role(user&.roles)
87
+ end
88
+
89
+ if user.blank?
90
+ scope = scope.where(authenticate_user: false)
91
+ end
92
+
93
+ unless unpublished
94
+ scope = scope.published
95
+ end
96
+
97
+ scope
98
+ }
99
+
100
+ before_validation(if: -> { current_user.present? }) do
101
+ self.owner ||= current_user
102
+ end
103
+
104
+ # Automatically approve submissions created by admins outside the submissions wizard
105
+ before_validation(if: -> { new_record? && classified_submission.blank? }) do
106
+ assign_attributes(status: :approved)
107
+ end
108
+
109
+ validates :title, presence: true, length: { maximum: 200 }
110
+ validates :category, presence: true
111
+ validates :body, presence: true
112
+
113
+ validates :start_on, presence: true
114
+ validates :end_on, presence: true
115
+ validates :location, presence: true
116
+
117
+ validates :organization, presence: true
118
+ validates :email, presence: true
119
+ validates :phone, presence: true
120
+
121
+ validate(if: -> { start_on.present? && end_on.present? }) do
122
+ self.errors.add(:end_on, 'must be after start date') if end_on < start_on
123
+ end
124
+
125
+ validate(if: -> { start_on.present? && end_on.present? && EffectiveClassifieds.max_duration.present? }) do
126
+ if (end_on - start_on) > EffectiveClassifieds.max_duration
127
+ distance = ApplicationController.helpers.distance_of_time_in_words(end_on + EffectiveClassifieds.max_duration, end_on).gsub('about', '').strip
128
+ self.errors.add(:end_on, "must be within #{distance} of start date")
129
+ end
130
+ end
131
+
132
+ validate(if: -> { category.present? }) do
133
+ self.errors.add(:category, 'is invalid') unless Array(EffectiveClassifieds.categories).include?(category)
134
+ end
135
+
136
+ def to_s
137
+ title.presence || 'New Classified'
138
+ end
139
+
140
+ def published?
141
+ return false unless approved?
142
+ return false if archived?
143
+ return false if start_on.blank? || (Time.zone.now < start_on)
144
+ return false if end_on.present? && (Time.zone.now >= end_on)
145
+ true
146
+ end
147
+
148
+ def submit!
149
+ submitted!
150
+ approve! if EffectiveClassifieds.auto_approve
151
+
152
+ after_commit do
153
+ EffectiveClassifieds.send_email(:classified_submitted, self)
154
+ end
155
+
156
+ true
157
+ end
158
+
159
+ def approve!
160
+ approved!
161
+ end
162
+
163
+ end
164
+ end
@@ -0,0 +1,7 @@
1
+ module Effective
2
+ class ClassifiedSubmission < ActiveRecord::Base
3
+ self.table_name = EffectiveClassifieds.classified_submissions_table_name.to_s
4
+
5
+ effective_classifieds_classified_submission
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ = tabs do
2
+ = tab 'Classified' do
3
+ = render 'admin/classifieds/form_classified', classified: classified
4
+
5
+ - if classified.persisted?
6
+
7
+ = tab 'Access' do
8
+ = render '/admin/classifieds/form_access', classified: classified
9
+
10
+ - if classified.respond_to?(:log_changes_datatable)
11
+ = tab 'Logs' do
12
+ = render_inline_datatable(classified.log_changes_datatable)
@@ -0,0 +1,10 @@
1
+ = effective_form_with(model: classified, url: classified.persisted? ? effective_classifieds.admin_classified_path(classified.id) : effective_classifieds.admin_classifieds_path) do |f|
2
+ = f.check_box :authenticate_user, label: 'Yes, the user must be be signed in to view this classified', hint: 'Sign up is required to register for any classified'
3
+
4
+ - if EffectiveClassifieds.use_effective_roles
5
+ = f.checks :roles, EffectiveRoles.roles_collection(f.object)
6
+
7
+ %p.text-hint
8
+ * leave blank for a regular public classified that anyone can view
9
+
10
+ = f.submit
@@ -0,0 +1,3 @@
1
+ = effective_form_with(model: [:admin, classified], engine: true) do |f|
2
+ = render('effective/classifieds/fields', f: f, classified: f.object)
3
+ = effective_submit(f)
@@ -0,0 +1,12 @@
1
+ = card do
2
+ .row
3
+ .col-sm
4
+ %h5.card-title= classified_submission.wizard_step_title(:classified)
5
+ .col-sm-auto.text-right
6
+ = link_to('Edit', wizard_path(:classified)) if edit_effective_classified_submissions_wizard?
7
+
8
+ - classified = classified_submission.classified
9
+
10
+ - if classified.present?
11
+ = render('effective/classifieds/classified', classified: classified) do
12
+ = classified.body
@@ -0,0 +1,8 @@
1
+ .effective-classified-submission
2
+ - blacklist = EffectiveClassifieds.ClassifiedSubmission.required_wizard_steps
3
+ - steps = classified_submission.required_steps - blacklist
4
+
5
+ = render "effective/classified_submissions/summary", classified_submission: classified_submission
6
+
7
+ - steps.select { |step| classified_submission.has_completed_step?(step) }.each do |partial|
8
+ = render "effective/classified_submissions/#{partial}", classified_submission: classified_submission, step: partial
@@ -0,0 +1 @@
1
+ -# Intentionally blank
@@ -0,0 +1,28 @@
1
+ -# In progress submission
2
+ - submission = EffectiveClassifieds.ClassifiedSubmission.in_progress.for(current_user).first
3
+ - datatable = EffectiveResources.best('EffectiveClassifiedSubmissionsDatatable').new(self, namespace: :effective)
4
+
5
+ - if submission.present?
6
+ %h2 In Progress Classified Submissions
7
+
8
+ %p
9
+ Your submission for #{submission.classified.presence || 'a classified'} is incomplete
10
+
11
+ %p
12
+ Please
13
+ = link_to("Continue submission for #{submission.classified.presence || 'a classified'}", effective_classifieds.classified_submission_build_path(submission, submission.next_step), 'data-turbolinks' => false, class: 'btn btn-primary')
14
+ or you can
15
+ = link_to('Abandon submission', effective_classifieds.classified_submission_path(submission), 'data-confirm': "Really delete #{submission}?", 'data-method': :delete, class: 'btn btn-danger')
16
+ to submit another.
17
+
18
+ %hr
19
+
20
+ %h2 Classified Submissions
21
+
22
+ - if datatable.present?
23
+ = render_simple_datatable(datatable)
24
+ - else
25
+ %p You have no past classified submissions. When you do, we'll show them here.
26
+
27
+ - if submission.blank?
28
+ %p= link_to 'Submit New Classified', effective_classifieds.new_classified_submission_path, class: 'btn btn-primary'
@@ -0,0 +1,3 @@
1
+ .row
2
+ .col-lg-3.mb-3= render_wizard_sidebar(resource)
3
+ .col-lg-9= yield
@@ -0,0 +1,30 @@
1
+ = card('Classified Submission') do
2
+ - classified = classified_submission.classified
3
+
4
+ %table.table.table-sm
5
+ %tbody
6
+ %tr
7
+ %th.border-0 Classified
8
+ %td.border-0
9
+
10
+ - if classified&.published?
11
+ = link_to(classified, effective_classifieds.classified_path(classified), target: '_blank')
12
+ - else
13
+ = classified.presence || 'Classified was deleted'
14
+
15
+ - if request.path.start_with?('/admin')
16
+ %tr
17
+ %th Owner
18
+ %td
19
+ - url = (polymorphic_admin_path(classified_submission.owner) rescue "/admin/users/#{classified_submission.owner.to_param}/edit")
20
+ = link_to(classified_submission.owner, url)
21
+ - else
22
+ %tr
23
+ %th Owner
24
+ %td= classified_submission.owner
25
+
26
+ - if classified&.was_submitted?
27
+ %tr
28
+ %th Status
29
+ %td
30
+ %span.badge.badge-secondary= classified.status
@@ -0,0 +1,17 @@
1
+ = render 'layout' do
2
+ = render 'effective/classified_submissions/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
7
+ = f.hidden_field :id
8
+
9
+ = f.fields_for :classified, (f.object.classified || f.object.build_classified) do |fc|
10
+ = fc.hidden_field :id
11
+
12
+ = fc.hidden_field :owner_id, value: f.object.owner_id
13
+ = fc.hidden_field :owner_type, value: f.object.owner_type
14
+
15
+ = render('effective/classifieds/fields', f: fc, classified: fc.object)
16
+
17
+ = f.save 'Save and Continue'
@@ -0,0 +1,16 @@
1
+ = render 'layout' do
2
+ = render 'effective/classified_submissions/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ %p Welcome #{current_user}!
7
+
8
+ %p You are about to submit a classified
9
+
10
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
11
+ = f.hidden_field :id
12
+
13
+ = f.hidden_field :owner_type
14
+ = f.hidden_field :owner_id
15
+
16
+ = f.save 'Save and Continue'
@@ -0,0 +1,13 @@
1
+ = render 'layout' do
2
+ = render 'effective/classified_submissions/content', resource: resource
3
+
4
+ - raise('expected a submitted classified_submission') unless resource.was_submitted?
5
+
6
+ .alert.alert-warning.mb-4
7
+ Successfully submitted on #{resource.submitted_at.strftime('%F')}.
8
+
9
+ = link_to "Return to Dashboard", root_path, class: 'btn btn-lg btn-primary mb-4'
10
+
11
+ = render 'effective/classified_submissions/classified_submission', classified_submission: resource
12
+
13
+ = link_to "Return to Dashboard", root_path, class: 'btn btn-lg btn-primary'
@@ -0,0 +1,8 @@
1
+ = render 'layout' do
2
+ = render 'effective/classified_submissions/content', resource: resource
3
+
4
+ = render('effective/classified_submissions/classified_submission', classified_submission: resource)
5
+
6
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
7
+ = f.hidden_field :id
8
+ = f.submit 'Submit Classified', class: 'btn btn-primary'
@@ -0,0 +1,50 @@
1
+ .card.effective-classified
2
+ .card-body
3
+ %h5.card-title= classified.title
4
+
5
+ %table.table.effective-classified-table
6
+ %tbody
7
+ %tr
8
+ %td Category
9
+ %td= classified.category
10
+
11
+ %tr
12
+ %td Available
13
+ %td #{classified.start_on&.strftime('%F')} to #{classified.end_on&.strftime('%F')}
14
+
15
+ %tr
16
+ %td Location
17
+ %td= classified.location.presence || '-'
18
+
19
+ %tr
20
+ %td Website
21
+ %td
22
+ - if classified.website.present?
23
+ = link_to(classified.website, classified.website, target: '_blank')
24
+ - else
25
+ = '-'
26
+
27
+ %tr
28
+ %td Contact
29
+ %td= classified.organization
30
+
31
+ %tr
32
+ %td Email
33
+ %td
34
+ - if classified.email.present?
35
+ = mail_to(classified.email)
36
+ - else
37
+ = '-'
38
+
39
+ %tr
40
+ %td Phone
41
+ %td
42
+ - if classified.phone.present?
43
+ = classified.phone
44
+ - else
45
+ = '-'
46
+
47
+ - if block_given?
48
+ = yield
49
+ - else
50
+ %p= link_to('View Classified', effective_classifieds.classified_path(classified), class: 'btn btn-primary')
@@ -0,0 +1,8 @@
1
+ %h2 Classifieds
2
+
3
+ - published = Effective::Classified.classifieds(user: current_user).count
4
+
5
+ - datatable = EffectiveClassifiedsDatatable.new(self, namespace: :effective)
6
+ = render_datatable(datatable, simple: true)
7
+
8
+ %p= link_to 'View All Classifieds', effective_classifieds.classifieds_path, class: 'btn btn-primary'
@@ -0,0 +1,28 @@
1
+ = f.text_field :title
2
+ = f.select :category, EffectiveClassifieds.categories, required: true
3
+
4
+ - if f.object.persisted? || f.object.errors.include?(:slug)
5
+ - current_url = (effective_classifieds.classified_url(f.object) rescue nil)
6
+ = f.text_field :slug, hint: "The slug controls this resource's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url }".html_safe
7
+
8
+ - minDate = [Time.zone.now, f.object.created_at].compact.min
9
+
10
+ = f.date_field :start_on, label: "Classified Start",
11
+ hint: 'The classified ad will be displayed starting on this date',
12
+ input_js: { minDate: minDate.strftime('%F') }
13
+
14
+ = f.date_field :end_on, label: "Classified End",
15
+ hint: 'The classified ad will no longer be displayed on this date'
16
+
17
+ - if f.object.persisted? && !f.object.draft?
18
+ = f.check_box :archived, label: 'Yes, this classified is archived and will not be displayed'
19
+
20
+ %h2 Classified Content
21
+ = f.rich_text_area :body, hint: 'The main body of your classified'
22
+ = f.text_field :location
23
+ = f.url_field :website
24
+
25
+ %h2 Contact Information
26
+ = f.text_field :organization
27
+ = f.email_field :email
28
+ = f.tel_field :phone
@@ -0,0 +1,3 @@
1
+ = effective_form_with(model: classified, engine: true) do |f|
2
+ = render('effective/classifieds/fields', f: f, classified: f.object)
3
+ = effective_submit(f)
@@ -0,0 +1 @@
1
+ = yield
@@ -0,0 +1,8 @@
1
+ %h1= @page_title
2
+
3
+ = render 'layout' do
4
+ .effective-classifieds
5
+ = render partial: @classifieds, spacer_template: 'spacer'
6
+
7
+ %nav.d-flex.justify-content-center
8
+ = bootstrap_paginate(@classifieds, per_page: EffectiveClassifieds.per_page)
@@ -0,0 +1,8 @@
1
+ = render 'layout' do
2
+ .effective-classified
3
+ - unless @classified.published?
4
+ .alert.alert-warning This classified is currently unavailable.
5
+
6
+ = render 'effective/classifieds/classified', classified: @classified do
7
+ .classified-body.classified-content
8
+ = @classified.body
@@ -0,0 +1,16 @@
1
+ %p Hello Admin!
2
+
3
+ - if @classified.published?
4
+ %p The following classified has been submitted and is published online:
5
+ - else
6
+ %p The following classified has been submitted and is awaiting your approval:
7
+ %p= link_to('Approve Classified', effective_classifieds.edit_admin_classified_path(@classified))
8
+
9
+ = render('effective/classifieds/classified', classified: @classified) do
10
+ %p= @classified.body
11
+
12
+ %hr
13
+
14
+ %p= link_to('View Classified', effective_classifieds.classified_path(@classified))
15
+
16
+ %p Have a great day!
@@ -0,0 +1,7 @@
1
+ !!!
2
+ %html{style: 'background: #fff;'}
3
+ %head
4
+ %meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => 'Content-Type'}
5
+
6
+ %body{style: 'background: #fff;'}
7
+ = yield
@@ -0,0 +1,45 @@
1
+ EffectiveClassifieds.setup do |config|
2
+ config.classifieds_table_name = :classifieds
3
+ config.classified_submissions_table_name = :classified_submissions
4
+
5
+ # Every classified must have a category.
6
+ config.categories = ['Job Board', 'Equipment Sales']
7
+
8
+ # Layout Settings
9
+ # Configure the Layout per controller, or all at once
10
+ # config.layout = { application: 'application', admin: 'admin' }
11
+
12
+ # Classified Settings
13
+ # config.classified_submission_class_name = 'Effective::ClassifiedSubmission'
14
+
15
+ # Pagination length on the Classified#index page
16
+ config.per_page = 10
17
+
18
+ # Classified can be restricted by role
19
+ config.use_effective_roles = true
20
+
21
+ # Automatically end classifieds after this duration
22
+ config.max_duration = 3.months
23
+
24
+ # Automatically approve classified submissions, otherwise require admin approval
25
+ config.auto_approve = false
26
+
27
+ # Mailer Configuration
28
+ # Configure the class responsible to send e-mails.
29
+ # config.mailer = 'Effective::ClassifiedsMailer'
30
+
31
+ # Configure the parent class responsible to send e-mails.
32
+ # config.parent_mailer = 'ActionMailer::Base'
33
+
34
+ # Default deliver method
35
+ # config.deliver_method = :deliver_later
36
+
37
+ # Default layout
38
+ # config.mailer_layout = 'effective_classifieds_mailer_layout'
39
+
40
+ # Default From
41
+ config.mailer_sender = "no-reply@example.com"
42
+
43
+ # Send Admin correspondence To
44
+ config.mailer_admin = "admin@example.com"
45
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ Rails.application.routes.draw do
4
+ mount EffectiveClassifieds::Engine => '/', as: 'effective_classifieds'
5
+ end
6
+
7
+ EffectiveClassifieds::Engine.routes.draw do
8
+ # Public routes
9
+ scope module: 'effective' do
10
+ resources :classifieds, only: [:index, :show, :edit, :update]
11
+
12
+ resources :classified_submissions, only: [:new, :show, :destroy] do
13
+ resources :build, controller: :classified_submissions, only: [:show, :update]
14
+ end
15
+
16
+ end
17
+
18
+ namespace :admin do
19
+ resources :classifieds, except: [:show] do
20
+ post :approve, on: :member
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,62 @@
1
+ class CreateEffectiveClassifieds < ActiveRecord::Migration[6.1]
2
+ def change
3
+ create_table <%= @classifieds_table_name %> do |t|
4
+ t.integer :classified_submission_id
5
+ t.string :classified_submission_type
6
+
7
+ t.integer :owner_id
8
+ t.string :owner_type
9
+
10
+ t.string :title
11
+ t.string :category
12
+
13
+ t.string :organization
14
+ t.string :location
15
+
16
+ t.string :website
17
+ t.string :email
18
+ t.string :phone
19
+
20
+ t.datetime :start_on
21
+ t.datetime :end_on
22
+
23
+ t.string :slug
24
+
25
+ t.string :status
26
+ t.text :status_steps
27
+
28
+ t.integer :roles_mask
29
+ t.boolean :authenticate_user, default: false
30
+
31
+ t.boolean :archived, default: false
32
+
33
+ t.timestamps
34
+ end
35
+
36
+ add_index :classifieds, [:owner_id, :owner_type]
37
+ add_index :classifieds, :slug
38
+
39
+ create_table <%= @classified_submissions_table_name %> do |t|
40
+ t.string :token
41
+
42
+ t.integer :owner_id
43
+ t.string :owner_type
44
+
45
+ # Acts as Statused
46
+ t.string :status
47
+ t.text :status_steps
48
+
49
+ # Acts as Wizard
50
+ t.text :wizard_steps
51
+
52
+ # Dates
53
+ t.datetime :submitted_at
54
+
55
+ t.datetime :updated_at
56
+ t.datetime :created_at
57
+ end
58
+
59
+ add_index :classified_submissions, [:owner_id, :owner_type]
60
+ add_index :classified_submissions, :token
61
+ end
62
+ end
data/db/seeds.rb ADDED
@@ -0,0 +1 @@
1
+ puts "Running effective_classifieds seeds"
@@ -0,0 +1,18 @@
1
+ module EffectiveClassifieds
2
+ class Engine < ::Rails::Engine
3
+ engine_name 'effective_classifieds'
4
+
5
+ # Set up our default configuration options.
6
+ initializer 'effective_classifieds.defaults', before: :load_config_initializers do |app|
7
+ eval File.read("#{config.root}/config/effective_classifieds.rb")
8
+ end
9
+
10
+ # Include acts_as_addressable concern and allow any ActiveRecord object to call it
11
+ initializer 'effective_classifieds.active_record' do |app|
12
+ ActiveSupport.on_load :active_record do
13
+ ActiveRecord::Base.extend(EffectiveClassifiedsClassifiedSubmission::Base)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module EffectiveClassifieds
2
+ VERSION = '0.0.2'.freeze
3
+ end