effective_classifieds 0.0.2
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +122 -0
- data/Rakefile +18 -0
- data/app/assets/config/effective_classifieds_manifest.js +3 -0
- data/app/assets/javascripts/effective_classifieds/base.js +0 -0
- data/app/assets/javascripts/effective_classifieds.js +1 -0
- data/app/assets/stylesheets/effective_classifieds/base.scss +0 -0
- data/app/assets/stylesheets/effective_classifieds.scss +1 -0
- data/app/controllers/admin/classified_submissions_controller.rb +19 -0
- data/app/controllers/admin/classifieds_controller.rb +20 -0
- data/app/controllers/effective/classified_submissions_controller.rb +31 -0
- data/app/controllers/effective/classifieds_controller.rb +53 -0
- data/app/datatables/admin/effective_classified_submissions_datatable.rb +22 -0
- data/app/datatables/admin/effective_classifieds_datatable.rb +61 -0
- data/app/datatables/effective_classified_submissions_datatable.rb +37 -0
- data/app/datatables/effective_classifieds_datatable.rb +25 -0
- data/app/helpers/effective_classifieds_helper.rb +7 -0
- data/app/mailers/effective/classifieds_mailer.rb +22 -0
- data/app/models/concerns/effective_classifieds_classified_submission.rb +112 -0
- data/app/models/effective/classified.rb +164 -0
- data/app/models/effective/classified_submission.rb +7 -0
- data/app/views/admin/classifieds/_form.html.haml +12 -0
- data/app/views/admin/classifieds/_form_access.html.haml +10 -0
- data/app/views/admin/classifieds/_form_classified.html.haml +3 -0
- data/app/views/effective/classified_submissions/_classified.haml +12 -0
- data/app/views/effective/classified_submissions/_classified_submission.html.haml +8 -0
- data/app/views/effective/classified_submissions/_content.html.haml +1 -0
- data/app/views/effective/classified_submissions/_dashboard.html.haml +28 -0
- data/app/views/effective/classified_submissions/_layout.html.haml +3 -0
- data/app/views/effective/classified_submissions/_summary.html.haml +30 -0
- data/app/views/effective/classified_submissions/classified.html.haml +17 -0
- data/app/views/effective/classified_submissions/start.html.haml +16 -0
- data/app/views/effective/classified_submissions/submitted.html.haml +13 -0
- data/app/views/effective/classified_submissions/summary.html.haml +8 -0
- data/app/views/effective/classifieds/_classified.html.haml +50 -0
- data/app/views/effective/classifieds/_dashboard.html.haml +8 -0
- data/app/views/effective/classifieds/_fields.html.haml +28 -0
- data/app/views/effective/classifieds/_form.html.haml +3 -0
- data/app/views/effective/classifieds/_layout.html.haml +1 -0
- data/app/views/effective/classifieds/_spacer.html.haml +1 -0
- data/app/views/effective/classifieds/index.html.haml +8 -0
- data/app/views/effective/classifieds/show.html.haml +8 -0
- data/app/views/effective/classifieds_mailer/classified_submitted.html.haml +16 -0
- data/app/views/layouts/effective_classifieds_mailer_layout.html.haml +7 -0
- data/config/effective_classifieds.rb +45 -0
- data/config/routes.rb +24 -0
- data/db/migrate/01_create_effective_classifieds.rb.erb +62 -0
- data/db/seeds.rb +1 -0
- data/lib/effective_classifieds/engine.rb +18 -0
- data/lib/effective_classifieds/version.rb +3 -0
- data/lib/effective_classifieds.rb +45 -0
- data/lib/generators/effective_classifieds/install_generator.rb +31 -0
- data/lib/generators/templates/effective_classifieds_mailer_preview.rb +4 -0
- data/lib/tasks/effective_classifieds_tasks.rake +8 -0
- 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,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,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,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 @@
|
|
1
|
+
= yield
|
@@ -0,0 +1 @@
|
|
1
|
+
%hr
|
@@ -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,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
|