diff --git a/app/components/edit_content_button_component.html.erb b/app/components/edit_content_button_component.html.erb new file mode 100644 index 0000000..129d44e --- /dev/null +++ b/app/components/edit_content_button_component.html.erb @@ -0,0 +1,30 @@ +
+ + + <%= render ModalComponent.new(show_close_button: false) do %> + <%= form_with model: [:admin, @editable_content], + html: { autocomplete: "off" } do |form| %> + <%= form.hidden_field :redirect_to, value: @redirect_to %> +

+ <%= form.label :content, @editable_content.key.capitalize, class: 'font-bold' %> +

+ <% if @editable_content.rich_text %> +

+ <%= form.textarea :content, class: "md:w-[56rem] md:h-[28rem]" %> +

+

+ <%= form.submit "Save", class: "ml-2 btn-md btn-blue" %> +

+ <% else %> +

+ <%= form.text_field :content, class: "w-80" %> +

+

+ <%= form.submit "Save", class: "btn-md btn-blue w-full" %> +

+ <% end %> + <% end %> + <% end %> +
diff --git a/app/components/edit_content_button_component.rb b/app/components/edit_content_button_component.rb new file mode 100644 index 0000000..b0a463e --- /dev/null +++ b/app/components/edit_content_button_component.rb @@ -0,0 +1,6 @@ +class EditContentButtonComponent < ViewComponent::Base + def initialize(context:, key:, rich_text: false, redirect_to: nil) + @editable_content = EditableContent.find_or_create_by(context:, key:, rich_text:) + @redirect_to = redirect_to + end +end diff --git a/app/components/editable_content_component.html.erb b/app/components/editable_content_component.html.erb new file mode 100644 index 0000000..a685f08 --- /dev/null +++ b/app/components/editable_content_component.html.erb @@ -0,0 +1,9 @@ +<% if @editable_content.has_content? %> + <% if @editable_content.rich_text %> + <%= helpers.markdown_to_html @editable_content.content %> + <% else %> + <%= @editable_content.content %> + <% end %> +<% else %> + <%= @default %> +<% end %> diff --git a/app/components/editable_content_component.rb b/app/components/editable_content_component.rb new file mode 100644 index 0000000..545d79b --- /dev/null +++ b/app/components/editable_content_component.rb @@ -0,0 +1,6 @@ +class EditableContentComponent < ViewComponent::Base + def initialize(context:, key:, rich_text: false, default: nil) + @editable_content = EditableContent.find_or_create_by(context:, key:, rich_text:) + @default = default + end +end diff --git a/app/controllers/admin/editable_contents_controller.rb b/app/controllers/admin/editable_contents_controller.rb index 10140a0..d8782cc 100644 --- a/app/controllers/admin/editable_contents_controller.rb +++ b/app/controllers/admin/editable_contents_controller.rb @@ -16,8 +16,14 @@ class Admin::EditableContentsController < Admin::BaseController end def update + return_to = params[:editable_content][:redirect_to].presence + if @editable_content.update(content_params) - render json: { status: "success", message: "Content updated" }, status: :ok + if return_to + redirect_to return_to + else + render status: :ok + end else render :edit, status: :unprocessable_entity end diff --git a/app/controllers/contributions/other_controller.rb b/app/controllers/contributions/other_controller.rb index e4bafff..d4e6a6b 100644 --- a/app/controllers/contributions/other_controller.rb +++ b/app/controllers/contributions/other_controller.rb @@ -4,12 +4,6 @@ class Contributions::OtherController < ApplicationController # GET /contributions/other def index - @content_title = EditableContent.find_or_create_by( - path: "contributions/other", key: "title" - ) - @content_body = EditableContent.find_or_create_by( - path: "contributions/other", key: "body", rich_text: true - ) @current_section = :contributions end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c166e06..47bf005 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -15,6 +15,10 @@ module ApplicationHelper tag.span text, class: "inline-flex items-center rounded-full bg-#{color}-100 px-2.5 py-0.5 text-xs font-medium text-#{color}-800" end + def markdown_to_html(string) + raw Kramdown::Document.new(string, { input: "GFM" }).to_html + end + def image_url_for(attachment) return s3_image_url(attachment) if Setting.s3_enabled? diff --git a/app/helpers/editable_content_helper.rb b/app/helpers/editable_content_helper.rb deleted file mode 100644 index b3d98b5..0000000 --- a/app/helpers/editable_content_helper.rb +++ /dev/null @@ -1,10 +0,0 @@ -module EditableContentHelper - def editable_content_for(path, key, default: nil, create_rich: false) - @content = EditableContent.find_by(path: "contributions/other", key: key) - @content.content.present? ? @content.content : default - end - - def markdown_to_html(string) - raw Kramdown::Document.new(string, { input: "GFM" }).to_html - end -end diff --git a/app/models/editable_content.rb b/app/models/editable_content.rb index 2bd5560..d051aa1 100644 --- a/app/models/editable_content.rb +++ b/app/models/editable_content.rb @@ -1,4 +1,12 @@ class EditableContent < ApplicationRecord validates :key, presence: true, - uniqueness: { scope: :path } + uniqueness: { scope: :context } + + def has_content? + content.present? + end + + def is_empty? + content.blank? + end end diff --git a/app/views/contributions/other/index.html.erb b/app/views/contributions/other/index.html.erb index 271eca2..f032e6d 100644 --- a/app/views/contributions/other/index.html.erb +++ b/app/views/contributions/other/index.html.erb @@ -1,42 +1,20 @@ <%= render HeaderComponent.new(title: "Contributions") %> <%= render MainWithTabnavComponent.new(tabnav_partial: "shared/tabnav_contributions") do %> - <% if @edit_content %> -
- <%= form_with model: [:admin, @content_title] do |form| %> -

- <%= form.label :content, @content_title.key.capitalize, class: 'font-bold' %> -

-

- <%= form.text_field :content %> - <%# <%= form.submit "Save", class: "btn-md btn-blue" %> - <%= button_tag type: 'submit', name: nil, title: "Save", class: 'btn-md btn-icon btn-outline' do %> - <%= render partial: "icons/save", locals: { custom_class: "text-blue-600 h-4 w-4 inline" } %> - <% end %> -

- <% end %> -
-
- <%= form_with model: [:admin, @content_body] do |form| %> -

- <%= form.label :content, @content_body.key.capitalize, class: 'font-bold' %> -

-

- <%= form.textarea :content, class: "w-full h-96" %> -

-

- <%= link_to 'Cancel', request.path, class: 'btn-md btn-gray' %> - <%= form.submit "Save", class: "ml-2 btn-md btn-blue" %> -

- <% end %> -
- <% else %> -
- <% if @content_body.content.present? %> - <%= markdown_to_html @content_body.content %> - <% else %> - No content yet - <% end %> -
- <% end %> +
+ <%= render EditableContentComponent.new( + context: "contributions/other", key: "body", rich_text: true, + default: "No content yet") %> + + <% if current_user.is_admin? %> +
+ <%= render EditContentButtonComponent.new( + context: "contributions/other", key: "title", + redirect_to: request.path) do %>Edit title<% end %> + <%= render EditContentButtonComponent.new( + context: "contributions/other", key: "body", rich_text: true, + redirect_to: request.path) do %>Edit content<% end %> +
+ <% end %> +
<% end %> diff --git a/app/views/shared/_tabnav_contributions.html.erb b/app/views/shared/_tabnav_contributions.html.erb index 2cc243b..1671502 100644 --- a/app/views/shared/_tabnav_contributions.html.erb +++ b/app/views/shared/_tabnav_contributions.html.erb @@ -6,7 +6,9 @@ active: current_page?(contributions_donations_path) ) %> <%= render TabnavLinkComponent.new( - name: editable_content_for("contributions/other", "title", default: "Other"), + name: render(EditableContentComponent.new( + context: "contributions/other", key: "title", default: "Other" + )), path: contributions_other_path, active: current_page?(contributions_other_path) ) %> diff --git a/db/migrate/20250528092931_create_editable_contents.rb b/db/migrate/20250528092931_create_editable_contents.rb index 0fac11e..85e54ab 100644 --- a/db/migrate/20250528092931_create_editable_contents.rb +++ b/db/migrate/20250528092931_create_editable_contents.rb @@ -1,7 +1,7 @@ class CreateEditableContents < ActiveRecord::Migration[8.0] def change create_table :editable_contents do |t| - t.string :path + t.string :context t.string :key t.string :lang, default: "en" t.text :content diff --git a/db/schema.rb b/db/schema.rb index b9dd900..087e218 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -65,7 +65,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_28_092931) do end create_table "editable_contents", force: :cascade do |t| - t.string "path" + t.string "context" t.string "key" t.string "lang", default: "en" t.text "content"