diff --git a/app/controllers/workshop_variation_ideas_controller.rb b/app/controllers/workshop_variation_ideas_controller.rb new file mode 100644 index 000000000..4409b59f2 --- /dev/null +++ b/app/controllers/workshop_variation_ideas_controller.rb @@ -0,0 +1,81 @@ +class WorkshopVariationIdeasController < ApplicationController + before_action :set_workshop_variation_idea, only: [ :show, :edit, :update, :destroy ] + + def index + per_page = params[:number_of_items_per_page].presence || 25 + workshop_variation_ideas = WorkshopVariationIdea.includes(:workshop, :created_by, :updated_by) + @workshop_variation_ideas_count = workshop_variation_ideas.size + @workshop_variation_ideas = workshop_variation_ideas.order(created_at: :desc) + .paginate(page: params[:page], per_page: per_page) + .decorate + end + + def show + end + + def new + @workshop_variation_idea = WorkshopVariationIdea.new + set_form_variables + end + + def edit + set_form_variables + end + + def create + @workshop_variation_idea = WorkshopVariationIdea.new(workshop_variation_idea_params) + + if @workshop_variation_idea.save + NotificationServices::CreateNotification.call( + noticeable: @workshop_variation_idea, + kind: :idea_submitted_fyi, + recipient_role: :admin, + recipient_email: ENV.fetch("REPLY_TO_EMAIL", "programs@awbw.org"), + notification_type: 0) + redirect_to workshop_variation_ideas_path, notice: "Workshop variation idea was successfully created." + else + set_form_variables + render :new, status: :unprocessable_content + end + end + + def update + if @workshop_variation_idea.update(workshop_variation_idea_params) + redirect_to workshop_variation_ideas_path, notice: "Workshop variation idea was successfully updated.", status: :see_other + else + set_form_variables + render :edit, status: :unprocessable_content + end + end + + def destroy + @workshop_variation_idea.destroy! + redirect_to workshop_variation_ideas_path, notice: "Workshop variation idea was successfully destroyed." + end + + private + + def set_workshop_variation_idea + @workshop_variation_idea = WorkshopVariationIdea.find(params[:id]) + end + + def set_form_variables + @workshop_variation_idea.build_primary_asset if @workshop_variation_idea.primary_asset.blank? + @workshop_variation_idea.gallery_assets.build + + @workshops = Workshop.published.order(:title) + @users = User.active.or(User.where(id: @workshop_variation_idea.created_by_id)) + .order(:first_name, :last_name) + end + + def workshop_variation_idea_params + params.require(:workshop_variation_idea).permit( + :name, :description, :youtube_url, + :inactive, :position, + :workshop_id, + :created_by_id, :updated_by_id, + primary_asset_attributes: [ :id, :file, :_destroy ], + gallery_assets_attributes: [ :id, :file, :_destroy ] + ) + end +end diff --git a/app/controllers/workshop_variations_controller.rb b/app/controllers/workshop_variations_controller.rb index a2bc3dbd4..7c6902eb0 100644 --- a/app/controllers/workshop_variations_controller.rb +++ b/app/controllers/workshop_variations_controller.rb @@ -16,7 +16,12 @@ def index end def new - @workshop_variation = WorkshopVariation.new + if params[:workshop_variation_idea_id].present? + @workshop_variation_idea = WorkshopVariationIdea.find(params[:workshop_variation_idea_id]) + @workshop_variation = WorkshopVariationFromIdeaService.new(@workshop_variation_idea, user: current_user).call + else + @workshop_variation = WorkshopVariation.new + end workshops = current_user.super_user? ? Workshop.all : Workshop.published @workshops = workshops.order(:title) @workshop = @workshop_variation.workshop || params[:workshop_id].present? && diff --git a/app/decorators/workshop_variation_idea_decorator.rb b/app/decorators/workshop_variation_idea_decorator.rb new file mode 100644 index 000000000..fe1ef28a4 --- /dev/null +++ b/app/decorators/workshop_variation_idea_decorator.rb @@ -0,0 +1,9 @@ +class WorkshopVariationIdeaDecorator < ApplicationDecorator + def detail(length: nil) + length ? description&.truncate(length) : description + end + + def default_display_image + "workshop_default.jpg" + end +end diff --git a/app/models/workshop_variation.rb b/app/models/workshop_variation.rb index bd7e90a31..a572d218e 100644 --- a/app/models/workshop_variation.rb +++ b/app/models/workshop_variation.rb @@ -3,6 +3,7 @@ class WorkshopVariation < ApplicationRecord belongs_to :workshop belongs_to :created_by, class_name: "User", optional: true + belongs_to :workshop_variation_idea, optional: true has_many :bookmarks, as: :bookmarkable, dependent: :destroy has_many :notifications, as: :noticeable, dependent: :destroy # Asset associations diff --git a/app/models/workshop_variation_idea.rb b/app/models/workshop_variation_idea.rb new file mode 100644 index 000000000..be518e150 --- /dev/null +++ b/app/models/workshop_variation_idea.rb @@ -0,0 +1,32 @@ +class WorkshopVariationIdea < ApplicationRecord + belongs_to :created_by, class_name: "User" + belongs_to :updated_by, class_name: "User" + belongs_to :workshop + has_many :bookmarks, as: :bookmarkable, dependent: :destroy + has_many :notifications, as: :noticeable, dependent: :destroy + has_many :workshop_variations + + # Asset associations + has_one :primary_asset, -> { where(type: "PrimaryAsset") }, + as: :owner, class_name: "PrimaryAsset", dependent: :destroy + has_many :gallery_assets, -> { where(type: "GalleryAsset") }, + as: :owner, class_name: "GalleryAsset", dependent: :destroy + has_many :assets, as: :owner, dependent: :destroy + + # Validations + validates :name, presence: true + validates :created_by_id, presence: true + validates :updated_by_id, presence: true + validates :workshop_id, presence: true + + # Nested attributes + accepts_nested_attributes_for :primary_asset, allow_destroy: true, reject_if: :all_blank + accepts_nested_attributes_for :gallery_assets, allow_destroy: true, reject_if: :all_blank + + # Scopes + scope :workshop_id, ->(workshop_id) { where(workshop_id: workshop_id) if workshop_id.present? } + + def title + name + end +end diff --git a/app/services/workshop_variation_from_idea_service.rb b/app/services/workshop_variation_from_idea_service.rb new file mode 100644 index 000000000..503121b7f --- /dev/null +++ b/app/services/workshop_variation_from_idea_service.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class WorkshopVariationFromIdeaService + def initialize(workshop_variation_idea, user:) + @workshop_variation_idea = workshop_variation_idea + @user = user + end + + def call + WorkshopVariation.new(attributes_from_idea).tap do |workshop_variation| + duplicate_assets(workshop_variation) + end + end + + private + + attr_reader :workshop_variation_idea, :user + + def attributes_from_idea + workshop_variation_idea.attributes.slice( + "name", "description", "youtube_url", + "position", "workshop_id" + ).merge( + created_by_id: user.id, + workshop_variation_idea_id: workshop_variation_idea.id, + inactive: true + ) + end + + def duplicate_assets(workshop_variation) + workshop_variation_idea.assets.each do |asset| + workshop_variation.assets.build(file: asset.file.blob) + end + end +end diff --git a/app/views/workshop_variation_ideas/_form.html.erb b/app/views/workshop_variation_ideas/_form.html.erb new file mode 100644 index 000000000..415e8533c --- /dev/null +++ b/app/views/workshop_variation_ideas/_form.html.erb @@ -0,0 +1,92 @@ +
| Main Image | +Name | +Workshop | +Author | +Promoted? | +Actions | +
|---|---|---|---|---|---|
|
+
+ <%= render "assets/display_image",
+ resource: workshop_variation_idea,
+ width: 18, height: 14,
+ variant: :index,
+ link_to_object: true,
+ file: workshop_variation_idea.display_image %>
+
+ |
+ <%= workshop_variation_idea.name %> | +<%= workshop_variation_idea.workshop.title %> | +<%= workshop_variation_idea.created_by.full_name %> | ++ <% if workshop_variation_idea.workshop_variations.any? %> + + <% else %> + -- + <% end %> + | + + ++ <%= link_to 'Edit', edit_workshop_variation_idea_path(workshop_variation_idea), class: "btn btn-secondary-outline" %> + | +
+ No workshop variation ideas found. +
+ <% end %> + + +Name:
+<%= @workshop_variation_idea.name %>
+Workshop:
+<%= @workshop_variation_idea.workshop.title %>
+Description:
+<%= @workshop_variation_idea.description %>
+YouTube URL:
+<%= @workshop_variation_idea.youtube_url %>
+Created by:
+<%= @workshop_variation_idea.created_by.full_name %>
+Position:
+<%= @workshop_variation_idea.position %>
+Inactive:
+<%= @workshop_variation_idea.inactive ? "Yes" : "No" %>
+